Repository pattern in MVC: controller code explanation - model-view-controller

What is the purpose of SudentRepository in this example? Why do I need one?
public class StudentController : Controller
{
private IStudentRepository _repository;
public StudentController() : this(new StudentRepository())
{
}
public StudentController(IStudentRepository repository)
{
_repository = repository;
}

I updated to actually include a specific question that I think you're getting at. The purpose of StudentRepository is to encapsulate interactions with persisted data. The Controller need not know if its stored in a db, flat file, in memory, etc.
The reason you're injecting it in via an interface is because you may eventually have multiple implementations of that repository, and the interface is just a contract to ensure basic functionality across all implementations. This is called constructor injection (a type of dependency injection) in case you want to learn more.

Related

How to inject ISession into Repository correctly?

Please correct me on the following scenario. ( Question is at the end)
(I asked a similar question that was un-organized and it was voted to close. So I have summarized the question here into a scope that can be replied with exact answers.)
I am developing a web application with multiple layers using nhibernate as ORM. My layer structure is as follow
Model Layer
Repository Layer
Services Layer
UI Layer
with the above layers, the classes and interfaces are placed as below.
ProductController.cs (UI Layer)
public class ProductController : Controller
{
ProductServices _ProductServices;
NHibernate.ISession _Session;
public ProductController()
{
_Session = SessionManager.GetCurrentSession();
_ProductServices = new ProductServices(
new ProductRepository(), _Session);
}
// Cont..
}
ProductServices.cs (Service Layer)
public class ProductServices : IProductServices
{
protected IProductRepository _ProductRepository;
protected NHibernate.ISession _Session;
public ProductServices(IProductRepository productRepository,
NHibernate.ISession session)
{
_ProductRepository = productRepository;
_Session = session;
_ProductRepository.SetSession(_Session);
}
// cont...
}
ProductRepository.cs (Repository Layer)
public class ProductRepository : IProductRepository
{
NHibernate.ISession _Session;
public void SetSession(NHibernate.ISession session)
{
_Session = session;
}
public IEnumerable<Product> FindAll()
{
return _Session.CreateCriteria<Product>().List<Product>();
}
//cont..
}
From the UI layer, I create the session as request per session and inject into service layer with the help of class constructor. Then set the session of repository with a help of a method.
I am afraid if I pass the _Session directly to repository as constructor, I will not have the control over it under the service layer. Also there is a future extension plan for using a webservice layer.
** Is there a way to ensure in each method of ProductRepository class that _Session is set already, without writing the piece of code if(_Session==null) in each and every method as it is repeating the same code.
** If the above pattern is wrong, Please show me a right way to achieve this goal.
What you are doing amazed me a bit. You applying the constructor injection pattern in the ProductService, which is definitely the way to go. On the other hand you are not injecting the dependencies into the ProductController, but that class is requesting one of those dependencies through a static class (this is the Service Locator anti-pattern) and creates a ProductServices class itself. This makes this class hard to test and makes your application less flexible and maintainable, since you can't easily change, decorate or intercept the use of the ProductServices class, when it's been used in multiple places.
And although you are (correctly) using constructor injection for the dependencies in the ProductServices, you are passing those dependencies on to the product repository, instead of applying the constructor injection pattern on the ProductResopistory as well.
Please show me a right way to achieve this goal.
The right way is to apply the constructor injection pattern everywhere. When you do this, your code will start to look like this:
public class ProductController : Controller
{
private ProductServices _ProductServices;
public ProductController(ProductServices services)
{
_ProductServices = services;
}
// Cont..
}
public class ProductServices : IProductServices
{
private IProductRepository _ProductRepository;
public ProductServices(
IProductRepository productRepository)
{
_ProductRepository = productRepository;
}
// cont...
}
public class ProductRepository : IProductRepository
{
private ISession _Session;
public ProductRepository (ISession session)
{
_Session = session;
}
public IEnumerable<Product> FindAll()
{
return _Session
.CreateCriteria<Product>().List<Product>();
}
//cont..
}
See how each class only takes in dependencies that it uses itself. So the ProductController and ProductServices don't depend on ISession (I made the assumption that only ProductRepoistory needs ISession). See how -from a class's perspective- everything is much simpler now?
Did we actually solve a problem here? It seems like we just moved the problem of wiring all classes together up the dependency graph. Yes we did move the problem. And this is a good thing. Now each class can be tested in isolation, is easier to follow, and the application as a whole is more maintainable.
Somewhere in the application however, a ProductController must be created. This could look like this:
new ProductController(
new ProductServices(
new ProductRepository(
SessionManager.GetCurrentSession())));
In its normal configuration, ASP.NET MVC will create controller classes for you, and it needs a default constructor to do so. If you want to wire up controllers using constructor injection (which you should definitely do), you need to do something 'special' to get this to work.
ASP.NET MVC allows you to override the default ControllerFactory class. This allows you to decide how to create controller instances. However, when your application starts to grow, it will get really awkward very quickly when you are creating your dependency graphs by hand (as my last example shows). In this case, it would be much better to use a Dependency Injection framework. Most of them contain a feature / package that allows you to integrate it with ASP.NET MVC and automatically allows to use constructor injection on your MVC controllers.
Are we done yet? Well... are we ever? There's one thing in your design that triggered a flag in my brain. Your system contains a class named ProductServices. Although a wild guess, the name Services seems like you wrapped all product related business operations inside that class. Depending on the size of your system, the number of people on your team, and the amount of changes you need to make, this might get problematic. For instance, how to you effectively apply cross-cutting concerns (such as logging, validation, profiling, transaction management, fault tolerance improvements) in such way that to system stays maintainable?
So instead of wrapping all operations in a single ProductServices class, try giving each business transaction / use case its own class and apply the same (generic) interface to all those classes. This description might be a bit vague, but it is a great way to improve the maintainability of small and big systems. You can read more about that here.
You can use a dependency injection container such as Autofac to instantiate your session and manage the lifetime of it. Leave the responsibility of instantiating the session to Autofac and simply inject the ISession interface into any classes that require the dependency. Have a look at this post: Managing NHibernate ISession with Autofac
You will also find this wiki page useful about configuring Autofac with MVC3: http://code.google.com/p/autofac/wiki/MvcIntegration3

Ninject Binding Issue with Constructor Chaining

I have a MVC3 project that uses the Entity Framework and Ninject v2.2, and follows the Unit of Work pattern with a Service Layer wrapping my repositories.
After looking at the code below, hopefully its apparent that Ninject is using constructor chaining to inject the correct classes. It currently works prefectly in my application, however I am at the point that I need to bind an instance of IDatabase to MyDatabase with a different scope such as InSingletonScope() or InNamedScope(), not InRequestScope(). I know that I can use the [Named("MyDatabaseScope")] Attribute to customize which IDatabase object is injected, however it seems that with my code structure, if I wanted to inject my SingletonScoped instance, I would have to recreate a new Abstract and Concrete Implementation of my Unit of Work, my Service and all my Repositories, that will then chain down.
Basically my application currently goes
Controller -> Unit of Work -> Database, (Repositories -> Database)
If I have to change my Database Binding, I will now have to create another chain in addition to the current one:
Controller -> New Unit of Work -> SingletonDatabase, (New Repositories-> SingletonDatabase)
This seems to completely defeat the DRY principal. Is there a way to, from the Controller Constructor, inform Ninject that when doing constructor chaining it should use my singleton (or named binding) rather than my request scope binding, without having to recreate all my classes with a Named attribute, or a new Interface?
Sorry for the long text, I wasnt sure if I could get the point across without my code snippets and my somewhat rambling explaination.
Ninject Module Load Function:
..snip..
Bind<IUserServices>().To<UserServices>();
Bind<IBaseServices>().To<BaseServices>();
Bind<IUserRepository>().To<UserRepository>();
Bind(typeof (IRepository<>)).To(typeof (RepositoryBase<>));
Bind<IUnitOfWork>().To<UnitOfWork>();
Bind<IDatabase>().To<MyDatabase>().InRequestScope();
//This is my problem:
//Bind<IDatabase>().To<MySingletonDatabase>().InSingletonScope();
Unit of Work Implementation Constructor:
public class UnitOfWork : IUnitOfWork
{
private IDatabase _database;
public UnitOfWork(IDatabase database,
IUserRepository userRepository,
IPeopleRepository peopleRepository,
)
{
this._database = database;
this.UserRepository = userRepository;
this.PeopleRepository = peopleRepository;
}
protected IDatabase Database
{
get { return _database; }
}
...snip...
}
User Service Layer Implementation Constructor:
public class UserServices : BaseServices, IUserServices
{
private IUnitOfWork _uow;
public UserServices(IUnitOfWork uow)
: base(uow)
{
_uow = uow;
}
...snip...
}
User Repository Constructor:
public class UserRepository : RepositoryBase<User>, IUserRepository
{
public UserRepository(IDatabase database)
: base(database)
{
}
...snip...
}
Controller Constructor:
public IUserServices _userServices { get; set; }
public ActivityController(IUserServices userServices)
{
_userServices = userServices;
}
}
Using Ninject 3.0.0 you can use WhenAnyAncestrorNamed("Some name") But if you need to run asyncronous things you should thing about splitting your application into a web frontend and a server backend. This could make many things easier.

Dependency Injection with Interface implemented by multiple classes

Update: Is there a way to achieve what I'm trying to do in an IoC framework other than Windsor? Windsor will handle the controllers fine but won't resolve anything else. I'm sure it's my fault but I'm following the tutorial verbatim and objects are not resolving with ctor injection, they are still null despite doing the registers and resolves. I've since scrapped my DI code and have manual injection for now because the project is time sensitive. Hoping to get DI worked out before deadline.
I have a solution that has multiple classes that all implement the same interface
As a simple example, the Interface
public interface IMyInterface {
string GetString();
int GetInt();
...
}
The concrete classes
public class MyClassOne : IMyInterface {
public string GetString() {
....
}
public int GetInt() {
....
}
}
public class MyClassTwo : IMyInterface {
public string GetString() {
....
}
public int GetInt() {
....
}
}
Now these classes will be injected where needed into layers above them like:
public class HomeController {
private readonly IMyInterface myInterface;
public HomeController() {}
public HomeController(IMyInterface _myInterface) {
myInterface = _myInterface
}
...
}
public class OtherController {
private readonly IMyInterface myInterface;
public OtherController() {}
public OtherController(IMyInterface _myInterface) {
myInterface = _myInterface
}
...
}
Both controllers are getting injected with the same interface.
When it comes to resolving these interfaces with the proper concrete class in my IoC, how do I differentiate that HomeController needs an instance of MyClassOne and OtherController needs an instance of MyClassTwo?
How do I bind two different concrete classes to the same interface in the IoC? I don't want to create 2 different interfaces as that breaks the DRY rule and doesn't make sense anyway.
In Castle Windsor I would have 2 lines like this:
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>());
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>());
This won't work because I will only ever get a copy of MyClassTwo because it's the last one registered for the interface.
Like I said, I don't get how I can do it without creating specific interfaces for each concrete, doing that breaks not only DRY rules but basic OOP as well. How do I achieve this?
Update based on Mark Polsen's answer
Here is my current IoC, where would the .Resolve statements go? I don' see anything in the Windsor docs
public class Dependency : IDependency {
private readonly WindsorContainer container = new WindsorContainer();
private IDependency() {
}
public IDependency AddWeb() {
...
container.Register(Component.For<IListItemRepository>().ImplementedBy<ProgramTypeRepository>().Named("ProgramTypeList"));
container.Register(Component.For<IListItemRepository>().ImplementedBy<IndexTypeRepository>().Named("IndexTypeList"));
return this;
}
public static IDependency Start() {
return new IDependency();
}
}
I hope you can use service overrides.
Ex.
container.Register(
Component.For<IMyService>()
.ImplementedBy<MyServiceImpl>()
.Named("myservice.default"),
Component.For<IMyService>()
.ImplementedBy<OtherServiceImpl>()
.Named("myservice.alternative"),
Component.For<ProductController>()
.ServiceOverrides(ServiceOverride.ForKey("myService").Eq("myservice.alternative"))
);
public class ProductController
{
// Will get a OtherServiceImpl for myService.
// MyServiceImpl would be given without the service override.
public ProductController(IMyService myService)
{
}
}
You should be able to accomplish it with named component registration.
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>().Named("One"));
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>().Named("Two"));
and then resolve them with
kernel.Resolve<IMyInterface>("One");
or
kernel.Resolve<IMyInterface>("Two");
See: To specify a name for the component
Typically DI containers follow Register, Resolve and Release patterns. During the register phase there are two steps. The first is to specify the mapping as you are doing. The second step is to specify the rules which govern which to inject where.
This problem is very common when we try to address Cross cutting concerns using decorators. In these situations, you have multiple classes(decorators) implementing a single interface.
Briefly, we need to implement IModelInterceptorsSelector which allows you to write imperative code that decides which Interceptor to apply to which types or members.
This is elaborately described in the book Dependency Injection in .Net book by Mark Seemann. Look for chapter 9 interception or search for the above interface.
I am not an expert at this, but was searching for the exact same problem and found the ans in the above book.
Hope this helps.
Regards
Dev1

ASP.Net MVC 3 - What is the best way to get logged-in username from within the repository?

I know that you can get the username of the currently logged in user from within the controller by using User.Identity.Name. However, my solution is split in 4 layers (4 projects):
MyProject.Domain for the models
MyProject.Data for the repositories
MyProject.Services where the business logic is
MyProject.Web for the controllers, the ViewModels and the Views
Now, my question is what is the best way the get the username of the current user from within the repository.
The thing is that all my models have 4 audit properties: CreatedBy, CreatedDate, ModifiedBy, ModifiedDate. And I am wondering how to populate the CreatedBy and the ModifiedBy properties when a model is stored to the database.
UPDATE:
Here is what I did following the advices I got below. I added an IUser interface in my Domain. I am not sure whether this is the best place to add this, but I decided to put it there, since my domain in referenced by all my other layers. I also added a User class to my controller layer (MyProject.Web), since this class needs access to the HttpContext, and this is the layer where it is accessible. To tell the truth, I did not know where such a class should be added in this layer. I have a Lib directory, so I put it in there.
Then I added a binding in MyProject.Web.App_Start.NinjectMVC3 like this:
private static void RegisterServices(IKernel kernel)
{
...
kernel.Bind<IUser>().To<User>();
}
I also added an IUser parameter to my base repository class constructor like this:
public abstract class RepositoryBase<T> where T : class, IEntity
{
#region Members
private UpDirContext dataContext;
private readonly IDbSet<T> dbset;
private readonly IUser user;
#endregion
protected RepositoryBase(IDatabaseFactory databaseFactory, IUser user)
{
DatabaseFactory = databaseFactory;
dbset = DataContext.Set<T>();
this.user = user;
}
...
So now, I can use "user" everywhere in my repositories. It is working, but I am not sure whether this is the best way of structuring things.
I also thought that I could use injection to pass IUser to my base entity class and make sure that the CreatedBy and ModifiedBy properties of my entities would be populated properly from the start, meaning object construction, but then my entities would not have had a constructor with zero parameter, and I did not want that.
UPDATE 2:
Here is an example of one of my services constructor:
public partial class SectorService : ISectorService
{
private readonly ISectorRepository sectorRepository;
private readonly IUnitOfWork unitOfWork;
public SectorService(ISectorRepository sectorRepository, IUnitOfWork unitOfWork)
{
this.sectorRepository = sectorRepository;
this.unitOfWork = unitOfWork;
}
...
I already use injections to get the repositories to the service layer. According to a comment below, IUser should be injected to the service layer, and I am wondering what is the best method to get User passed from this layer to the repositories.
Using dependency injection, inject an IUser at your composition root (ie your controller's constructor - all the main DI containers support it plius mvc supports it). The concrete implementation of IUser references HttpContext.Current.User.Identity.Name. All of the receivers of IUser don't need to care about where it came from.
I'm not following why though you asked about createdby, etc. Is this a separate question or are you referring to membership information?
My practice as of late is to pass it from controller -> service, then service -> repository, if necessary. This is because I want two websites (think public facing website and private API website) to use the same models/repositories/services, but the authentication methods for each are different.

Property Injection without attributes using Ninject in an abstract base controller in MVC3

I have the following code:
public abstract class BaseController : Controller
{
public IUserService UserService { get; set; }
}
All my controllers inherit from this base controller. I started out by configuring it in Ninject using the following code:
kernel.Bind<BaseController>()
.ToSelf()
.WithPropertyValue("UserService", x => x.Kernel.GetService(typeof(IUserService)));
This did not work. I assume it is because of the fact that the BaseController is an abstract class (please confirm my assumption). So I moved on to modify the configuration to:
kernel.Bind<HomeController>()
.ToSelf()
.WithPropertyValue("UserService", x => x.Kernel.GetService(typeof(IUserService)));
This does work. The minor downside is that I now have to configure every controller the same way.
Since I also have DependencyResolver setup in my ASP.NET MVC 3 project I could also remove the above Ninject configuration and modify my base controller to look like:
public IUserService UserService
{
get
{
return DependencyResolver.Current.GetService<IUserService>();
}
}
Is there any benefit to using the fluent configuration as opposed to using the DependencyResolver approach? Is one better than the other? Which approach would be considered a better practice?
It is worth mentioning that I did not want to do constructor injection in my base controller.
A better practice in MVC it is to use constructor injection over property injection. Why did you make your choice like this ?
Using Constructor Injection you states that all dependencies in constructor are necessary for the class to do its job.
Property injection means that the dependencies are optional or that there are the local defaults implementations, so all will work even if you don't provide necessary implementations yourself.
You should really know what you're doing using Property injection or you have no other choice, so the safer approach is to rely on constructor injection.
Now I'll give you my point of view. Other may have other opinions.
DependencyResolver was introduced in MVC 3 for "convenient" service location but for me it's a regular Service locator which for me is also an anti-pattern http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx. I don't use it because I don't like it and there is no benefit in using it.
I prefer to user my controller factory like before and pass the dependencies through constructor.
More the IDependencyResolver has somme issues with some IoC containers (I don't know if it's the case with Ninject). You can read more here : http://mikehadlow.blogspot.com/2011/02/mvc-30-idependencyresolver-interface-is.html
If you need the same dependency in each controller then there seems to be something wrong in your design. Most likely you are handling some kind of cross cutting concern in your base controller. In this case Doing property injection is just treating sympthoms instead of cureing the disease. This should rather be handled by an aspect (e.g. a filter or an interceptor) so that you do not have to pollute your controller with something that does not belong there.
There are many ways to skin the cat they say. You could use conventions-based bindings with .WithPropertyValue() or with .OnActivaction() (as described here).
public class ControllerModule : NinjectModule
{
public override void Load()
{
// Get all controller types derived from the base controller.
IEnumerable<Type> controllerTypes = // ...
foreach (var controllerType in controllerTypes)
{
Bind(controllerType).ToSelf().InRequestScope()
.WithPropertyValue(...);
}
}
}
You could create your own custom implementation of the IInjectionHeuristic interface as described here or your own custom implementation of the IControllerActivator interface.
public class CustomNinjectControllerActivator : IControllerActivator
{
private readonly IKernel kernel;
public CustomNinjectControllerActivator(IKernel kernel)
{
this.kernel = kernel;
}
public IController Create(RequestContext context, Type controllerType)
{
var baseController = kernel.TryGet(controllerType) as BaseController;
if (baseController == null)
{
return null;
}
baseController.UserService = kernel.Get<IUserService>();
return baseController;
}
}
Heck, you could even use the service locator pattern if you are comfortable using it.
public IUserService UserService
{
get { return DependencyResolver.Current.GetService<IUserService>(); }
}
You should choose whichever solution is easiest to implement, test and maintain, and of course provides the desired behavior.

Resources