MVC-3 Project Structure - asp.net-mvc-3

I have the following for a project structure, these are all seperate projects, I was told to do it that way so not my choice.
CORE
--Self Explanitory
DATA
--Contains EF 4.1 EDMX, POCO's Generic Repository Interface
DATAMapping
--Contains Generic Repository
Services
-- Contains nothing at the moment
MVC 3 Application
-- Self Explanitory
Here is my question. I have been reading that it is best practice to keep the controllers on a diet and that models / viewmodels should be dumb therefore introducing the service layer part of my project structure. The actual question now; Is this a good approach or am I creating way too much work for myself?
So if I want to say have some CRUD ops on products or categories or any of the other entities, the repository should be instantiated from the service layer / Business Logic Layer?
Some input please??

Personally I have my service layer referencing only generic and abstract repositories for CRUD operations. For example a service layer constructor might look like this:
public class MyService: IMyService
{
private readonly IFooRepository _fooRepo;
private readonly IBarRepository _barRepo;
public MyService(IFooRepository fooRepo, IBarRepository barRepo)
{
_fooRepo = fooRepo;
_barRepo = barRepo;
}
public OutputModel SomeBusinessMethod(InputModel input)
{
// ... use CRUD methods on _fooRepo and _barRepo to define a business operation
}
}
and the controller will simply take an IMyService into his constructor and use the business operation.
Then everything will be wired by the dependency injection framework of your choice.

Related

Where to put my queries - model vs. controller

I just switched from ActiveRecord/NHibernate to Dapper. Previously, I had all of my queries in my controllers. However, some properties which were convenient to implement on my models (such as summaries/sums/totals/averages), I could calculate by iterating over instance variables (collections) in my model.
To be specific, my Project has a notion of AppSessions, and I can calculate the total number of sessions, plus the average session length, by iterating over someProject.AppSessions.
Now that I'm in Dapper, this seems confused: my controller methods now make queries to the database via Dapper (which seems okay), but my model class also makes queries to the database via Dapper (which seems strange).
TLDR: Should the DB access go in my model, or controller, or both? It seems that both is not correct, and I would like to limit it to one "layer" so that changing DB access style later doesn't impact too much.
You should consider using a repository pattern:
With repositories, all of the database queries are encapsulated within a repository which is exposed through public interface, for example:
public interface IGenericRepository<T> where T : class
{
T Get(object id);
IQueryable<T> GetAll();
void Insert(T entity);
void Delete(T entity);
void Save(T entity);
}
Then you can inject a repository into a controller:
public class MyController
{
private readonly IGenericRepository<Foo> _fooRepository;
public MyController(IGenericRepository<Foo> fooRepository)
{
_fooRepository = fooRepository;
}
}
This keeps UI free of any DB dependencies and makes testing easier; from unit tests you can inject any mock that implements IRepository. This also allows the repository to implement and switch between technologies like Dapper or Entity Framework without any client changes and at any time.
The above example used a generic repository, but you don't have to; you can create a separate interface for each repository, e.g. IFooRepository.
There are many examples and many variations of how repository pattern can be implemented, so google some more to understand it. Here is one of my favorite articles re. layered architectures.
Another note: For small projects, it should be OK to put queries directly into controllers...
I can't speak for dapper personally, but I've always restricted my db access to models only except in very rare circumstances. That seems to make the most sense in my opinion.
A little more info: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
A model notifies its associated views and controllers when there has been a change in its state. This notification allows the views to produce updated output, and the controllers to change the available set of commands. A passive implementation of MVC omits these notifications, because the application does not require them or the software platform does not support them.
Basically, data access in models seems to be the standard.
I agree with #void-ray regarding the repository model. However, if you don't want to get into interfaces and dependency injection you could still separate out your data access layer and use static methods to return data from Dapper.
When I am using Dapper I typically have a Repository library that returns very small objects or lists that can then be mapped into a ViewModel and passed to the View (the mapping is done by StructureMap, but could be handled in the controller or another helper).

MVC: Repository and Viewmodels both pattern together for better structure?

If I want to combine using repositorys per entity and Viewmodels per view how does it work out?
Any website tips I could look up? Maby someone could give an easy example?
Thanks
Best Regards!
I like the following structure (from the famous Steven Sanderson's Pro ASP.NET MVC series):
Domain Project (Business Logic):
Abstract Folder (repository interfaces)
Concrete Folder (repository implementations)
Entities (EF generated classes)
Web UI Project (MVC Web App):
Models (view models)
Views
Controlers
etc, you get the point
The main thing is you're separating your business logic (which should house your repositories) from your Web UI (the MVC project)
In this scenario, your Controller classes reference the domain layer and use DI/IoC to call up the correct instance of the repository.
Example controller class:
namespace MyMvcProject
{
using System.Whatever;
using MyDomainLayer;
public class MyController : Controller
{
private readonly IMyRepository _myRepository;
public MyController(IMyRepository myRepository)
{
// Resolved using your favorite DI/IoC Container:
this._myRepository = myRepository;
}
public ActionResult DoSomething()
{
var stuff = _myRepository.GetStuff();
return View(stuff);
}
}
}
Use AutoMapper to copy data from entities to models and vice-versa.
This will reduce a lot of 'plumbing' code you will have to write otherwise.
I'm not a professional developer but I think Steve Sanderson's model is not the right model for some projects because you are working in your views against the model directly. What happen if you want to show only a few properties and not all of them? Your full model is traveling to the view.
I think your views must work against viewmodel classes and not directly the model coming from orm (trough repository, etc.)
The only problem that I'm finding is the mapping process between model to viewmodel and viewmodel to model. Let me explain...
I was trying to do this mapping with automap, the direction between model -> viewmodel works fine, but in the other direction (viewmodel to model) I'm not finding the way to do it automatically because the viewmodel, normally does not own all the properties that model have and if you do an automap to model object a lot of properties are empty.
Finally you need to make always some manual mappings.
Ideas for this situation may be welcome.
Thanks

Using Ninject in a SOLID application architecture

I'm starting with MVC3 and want to use some flexible architecture, so I've read tens of blogs, a book (Pro ASP.NET MVC 3), read about SOLID principles and finally got to an application structure I like (or at least I think so, so far, because I haven't built anything on it yet):
In this structure:
Domain holds the POCO classes and defines the service interfaces
Services implements service interfaces and defines repositories interfaces
Data implements repositories interfaces
WebUI and Domain use Services
Services use Repositories
WebUI, Services and Data depend on Domain for POCO classes
The main reason for Domain using Services is to validate unique keys on the Validate methods of POCO (IValidatable) classes.
I'm starting to build a reference application with this structure but I have faced, so far, two problems:
I'm using a Data.Tests project with unit tests for the repositories, but haven't found a way to inject (using Ninject) a implementation of the service (in the constructor or otherwise) on the model, so the Validate method can call the CheckUniqueKey on the service.
I haven't found any reference about hooking up Ninject to a TEST project (lots of for the WebUI project).
What I'm trying to achive here is beeing able to switch from EF to something else like DAPPER, by just changing the DATA assembly.
UPDATE
Right now (as of 09-AUG-2011) Ninject is working but I think I'm missing something.
I have a CustomerRepository with two constructors:
public class CustomerRepository : BaseRepository<Customer>, ICustomerRepository
{
// The repository usually receives a DbContext
public CustomerRepository(RefAppContext context)
: base(context)
{
}
// If we don't receive a DbContext then we create the repository with a defaulte one
public CustomerRepository()
: base(RefApp.DbContext())
{
}
...
}
On the TestInitialize:
// These are for testing the Repository against a test database
[TestInitialize()]
public void TestInitialize()
{
// Context used for tests
this.context = new RefAppContext();
// This is just to make sure Ninject is working,
// would have used: repository = new CustomerRepository(context);
this.kernel = NinjectMVC3.CreateKernel();
this.kernel.Rebind<ICustomerRepository>().To<CustomerRepository>().WithConstructorArgument("context", context);
this.repository = kernel.Get<ICustomerRepository>();
}
On the Customer class:
public class Customer : IValidatableObject
{
...
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// I want to replace this with a "magic" call to ninject
CustomerRepository rep = new CustomerRepository();
Customer customer = rep.GetDupReferenceCustomer(this);
if (customer != null)
yield return new ValidationResult("Customer \"" + customer.Name + "\" has the same reference, can't duplicate", new [] { "Reference" });
}
...
}
What would be the best way to use Ninject in this scenario?
Any help will be highly appreciated.
ANSWER, SORT OF
I'll consider this question as aswered so far. I could get Ninject working, sort of, but it looks like achiving the Dependency Inversion Principle (DIP) of SOLID is going to take some more time.
In that respect, I had to lump together Domain, Services and Data, I'll create another question some other time and keep the project going the usual way for now.
Thanks everybody.
Unit testing should be done without Ninject. Just create an instance of the object under test and inject a mock for every dependency manually.
For Integration Tests you can use the kernel inclusive all bindings from the application bootstrapper and rebind everything you want to replace by a Mock. e.g. Replace the Session binding by one that uses an in memory data storage instead of a real database.

good practice mvc with spring

with spring, when we have a service layer, dao layer and controller to manage a form data (list, selected list value, data found by the bd)
is it a good practice to put all this data in a object?
is a good practice to create a method in the service layer who will call many dao method to feed listbox... and feed a ford object or it's better
to call different method in the service layer from the controller ?
public class UserForm {
private SearchCritera searchCritera;
private List<String> city;
private List<String> country;
...
}
public class SearchCritera {
private List<String> selectedCity;
private List<String> selectedCountry;
...
}
maybe there are a better way that the two idea I proposed?
To me, it makes more sense to have what you suggested:
a DAO layer where you access the database with single operations
a service layer where you aggregate calls to the DAO layer and do some business logic
a web / controller layer where you make calls to the service layer and do what is necessary for the view to be rendered.
Keep in mind that either way you're designing your application, you have to configure it so that the transactions are dealt with properly. If your service layer is transactionnal and there are multiple calls from the web layer within the same method to the service layer, then if something goes wrong, likely the database might not end up in a clean state.
What you want to avoid too is to have business logic in your controller layer.

LINQ-to-XYZ polymorphism?

I have a situation where a client is requiring that we implement our data access code to use either an Oracle or SQL server database based on a runtime configuration settings. The production environment uses Oracle but both dev and QA are running against a SQL Server instance.
(I don't have any control over this or have any background on why this is the case other than Oracle is their BI platform and dev wants to work with SQL Server.)
Their request is to use LINQ-to-SQL / LINQ-to-Oracle for all data access. They will need to support the application and do not have the knowledge to jump into EF yet (their requirement) - although I believe the same problem exists if we use EF.
While I can implement LINQ to XYZ classes for both databases so that I can connect to both, they don't share a common interface (other than DataContext) so I really can't code against an interface and plug the actual implementation in at runtime.
Any ideas how I should approach this?
UPDATE
After writing this post, I did a little investigating into EF and it appears to me that this same problem exists if I use EF - which would be my long term goal.
Just a quick thought. Use MEF framework and plug your DAL layers to it. Then based on the environment(dev, production, QA) you can switch to the various DAL layers(Oracle, SQL etc.).
If you want to know about MEF , here is a quick intro.
Also sometime back I have seen a Generic Data Access Framework by Joydip Kanjilal. You can even have a look into that.
What you have to do is encapsulate the ORM datacontext in an interface of your creation, like IDataContext.
Then share this interface between all DALs and implement it. How you will plug it in is just your preference, using MEF as suggested or a IoC container.
For the sake of closure on this topic, here is what I ended up doing:
I implemented a combination of the Unit of Work and Repository patterns. The Unit of Work class is what consuming code works with and exposes all of the operations that can be performed on my root entities. There is one UoW per root entity. The UoW makes use of a repository class via an interface. The actual implementation of the repository is dependent on the data access technology being used.
So, for instance, if I have a customer entity and I need to support retrieving and updating each record, I would have something like:
public interface ICustomerManager
{
ICustomer GetCustomer(Guid customerId);
void SaveCustomer(ICustomer customer);
}
public class CustomerManager : ICustomerManager
{
public CustomerManager(ICustomerRepository repository)
{
Repository = repository;
}
public ICustomerRepository Repository { get; private set; }
public ICustomer GetCustomer(Guid customerId)
{
return Repository.SingleOrDefault(c => c.ID == customerId);
}
public void SaveCustomer(ICustomer customer)
{
Repository.Save(customer);
}
}
public interface ICustomerRepository : IQueryable<ICustomer>
{
void Save(ICustomer customer);
}
I'm using an Inversion of Control framework to inject the ICustomerRepository implementation into the CustomerManager class at runtime. The implementation class will be in a separate assembly that can be swapped out as the data access technology is changed. All we are concerned about is that the repository implements each method using the contract defined above.
As a side note, to do this with Linq-to-SQL, I simply created a LinqCustomerRepository class that implements ICustomerRepository and added a partial class for the generated Customer entity class that implements ICustomer. Then I can return the L2S entity from the repository as the implementation of the ICustomer interface for the UoW and calling code to work with and they'll be none the wiser that the entity originated from L2S code.

Resources