Consider:
public class HomeController : Controller
{
private IDependency dependency;
public HomeController(IDependency dependency)
{
this.dependency = dependency;
}
}
And the fact that Controllers in ASP.NET MVC must have one empty default constructor is there any way other than defining an empty (and useless in my opinion) constructor for DI?
If you want to have parameterless constructors you have to define a custom controller factory. Phil Haack has a great blog post about the subject.
If you don't want to roll your own controller factory you can get them pre-made in the ASP.NET MVC Contrib project at codeplex/github.
You don't have to have the empty constructor if you setup a custom ControllerFactory to use a dependency injection framework like Ninject, AutoFac, Castle Windsor, and etc. Most of these have code for a CustomControllerFactory to use their container that you can reuse.
The problem is, the default controller factory doesn't know how to pass the dependency in. If you don't want to use a framework mentioned above, you can do what is called poor man's dependency injection:
public class HomeController : Controller
{
private IDependency iDependency;
public HomeController() : this(new Dependency())
{
}
public HomeController(IDependency iDependency)
{
this.iDependency = iDependency;
}
}
Take a look at MVCContrib http://mvccontrib.github.com/MvcContrib/. They have controller factories for a number of DI containers. Windsor, Structure map etc.
You can inject your dependency by Property for example see: Injection by Property
Using Ninject looks like this:
[Inject]
public IDependency YourDependency { get; set; }
Related
I read a bout IDependencyResolver in MVC (fundamentalbook), but i don't know what is exactly DependencyResolver in mvc?
Could some one please explain these methods?
It allows for implementing dependency injection into controllers and other components. Brad Wilson wrote a nice article about it. For example when you implement a custom dependency resolver that is capable of returning proper implementations for a give type you could have your ASP.NET MVC controllers take abstract dependencies or interfaces as constructor arguments:
public class HomeController: Controller
{
private readonly ISomeService _someService;
public class HomeController(ISomeService someService)
{
_someService = someService;
}
... some actions
}
if you have written a custom dependency resolve it will be able to inject the proper implementation of the interface when instantiating the controller.
Dependency Injection allows for weaker coupling between the different layers of your application and making them easier to unit test in isolation.
I set up "Ninject" in my asp.mvc project. And it works fine each controller get its dependency classes. But I have one class in mvc project that is not controller. It's a simple class that extends "MembershipProvider" (because I have made custom membership) and I need to inject "UserRepository" class in it.
In a NinjectControlelrFactory I bint it:
private void AddBindings()
{
ninjectKernel.Bind<IUserRepository>().To<UserRepository>().WithConstructorArgument(
"connectionString", ConfigurationManager.ConnectionStrings["connStr"].ConnectionString);
}
But how to get it from non controller class?
PS
I can't inject through constructor.
I have some solution but I don't know how 'clean' it is:
using (IKernel kernel = new StandardKernel())
{
kernel.Bind<IUserRepository>()
.To<UserRepository>()
.WithConstructorArgument("connectionString", "ttttttttttttt");
//var tc = kernel.Get<IUserRepository>();
this.userRepository = kernel.Get<IUserRepository>();
}
Use Property Injection. Register your MembershipProvider in the Ninject and use Property injection.
You will need to instantiate MembershipProvider via ninject context.
Check these articles.
Property Injection in ASP.NET MVC with Ninject
Injecting properties in Ninject 2 without 'Inject' attribute
What is the best way to manage the context of Entity Framework when using MVC application?
I am using a Repository/Service pattern.
Edit
After looking through some of these questions: stackoverflow.com/users/587920/sam-striano, I am more confused then before. Some say use the context per repository, but wht if I want to use multiple repositories in one controller method?
And to follow good separation design, how do you use UnitOfWork in the MVC app with out making it dependent on EF? I want to be able to unit test my controllers, model, services, etc. using a mock context?
Use a Dependency Injector/Inversion of Control framework like:
Ninject
Autofac
StructureMap
Unity
Using an IoC container, you can tell it how to manage a single data context (most commonly, per request). When you set the data context to per request, the container will auto-magically give any class that needs a data context the same data context per request.
Here is a good article on setting up Ninject.
What your code will most likely end up looking like, assuming you're using a generic repository:
Ninject Module:
public class NinjectRegistrationModule : NinjectModule
{
public override void Load()
{
Bind<MyDataContext>().ToSelf().InRequestScope();
Bind(typeof(RepositoryImplementation<>)).ToSelf().InRequestScope();
}
}
Generic Repository:
public RepositoryImplementation<T> : IRepository<T> where T : class
{
MyDataContext _dataContext;
public RepositoryImplementation<T>(MyDataContext dataContext)
{
_dataContext = dataContext;
}
// bunch of methods that utilize _dataContext
}
Service Class:
public class MyServiceClass
{
IRepository<SomeEntity> _someEntityRepository;
public MyServiceClass(IRepository<SomeEntity> someEntityRepository)
{
_someEntityRepository = someEntityRepository;
}
// do stuff with _someEntityRepository = someEntityRepository;
}
Controller:
public class MyController
{
MyServiceClass _myServiceClass;
public MyController(MyServiceClass myServiceClass)
{
// Ninject will auto-magically give us a myServiceClass
// which will Ninject will inject a repository into MyServiceClass's constructor
_myServiceClass = myServiceClass;
}
public ActionResult MyAction()
{
// use _myServiceClass to do stuff
return View();
}
}
If your functionality is straight forward, then you should create a new ObjectContext in each Repository. They are cheap to instantiate.
If this creates a conflict, you can use a Unit of Work pattern as was suggested in the comment.
I would advise that you be extremely cautious when integrating an ObjectContext or DataContext with a DI container. Many do not use the appropriate scope for their life cycle by default.
Recently I moved to MVC 3 and Ninject 2. In most of the code, I use constructor injection, but there are some places, where I had to use Inject attribute. Ninject 2 registers its own IDepencyResolver interface. I don't like DependencyResolver class being part of System.Web.Mvc namespace, because its function is not really strictly related to MVC, but now, when it is there, I can do
public SomeClass
{
public IUserService UserService { get; set; }
public SomeClass()
{
UserService = DependencyResolver.Current.GetService<IUserService>();
instead of
public SomeClass
{
[Inject]
public IUserService UserService { get; set; }
so I don't have to reference Ninject namespace in my classes. Should DependencyResolver be used like that?
I use property injection only for dependencies that are not required for the proper working of the class but could add some functionality if the user sets them. Example of such functionality is logging. So you could have a property which represents a logger where the user can supply his own implementation and if he doesn't the class continues to work normally but it simply doesn't log.
For everything else I use constructor injection. This way you indicate to the consumer that this class has a required dependency on some other service.
So to answer your question about the property injection I would simply have:
public SomeClass
{
public IUserService UserService { get; set; }
public void SomeMethodWhichDoesntEnforceUserService()
{
if (UserService != null)
{
// Provide some additional functionality
}
}
}
and if your class cannot function properly without the user service:
public SomeClass
{
private readonly IUserService _userService;
public SomeClass(IUserService userService)
{
_userService = userService;
}
public void SomeMethodWhichRequiresTheService()
{
_userService.DoSomething();
}
}
So in both cases no reference to any DI specifics. That's what Inversion of Control is all about.
First question I would ask is why you can not perform constructor injection of the IUserService into SomeClass? It may indicate an issue with the design.
To avoid direct reference to the DependencyResolver you could implement some form of abstraction of a Service Locator over the DI framework, e.g. CommonServiceLocator, but as the answer to this question indicates, such abstractions shouldn't be necessary when doing DI correctly. Instead you should adjust the design of the application.
I believe the ninject.web.mvc version for mvc3 now supports constructor injection on filter attributes. Have you tried it?
I'm new to Ninject and I'm having problems using it with a custom membership provider.
My membership provider has a repository interface passed in. It looks like:
public class CustomMembershipProvider : MembershipProvider
{
public CustomMembershipProvider( IRepository repository )
{
}
}
I'm using the code thats part of the Account Model in the MVC app as a starting point.
However when it calls Membership.Provider I get an error saying No parameterless constructor defined for this object.
I've setup the bindings in ninject to bind a IRepository to a Repository class which work as I've testing this in a controller.
What are the correct bindings in Ninject to use for Membership.Provider?
This is how it should be done today with new versions of both MVC and Ninject (version 3):
You have access to the DependencyResolver instance and Ninject sets itself as the current DependencyResolver. That way you don't need hacks to get access to the static Ninject kernel. Please note, my example uses my own IUserService repository for Membership...
IUserService _userService = DependencyResolver.Current.GetService<IUserService>();
The best solution I found was the following:
private IRepository _repository;
[Inject]
public IRepository Repository
{
get { return _repository; }
set { _repository= value; }
}
public CustomMembershipProvider()
{
NinjectHelper.Kernel.Inject(this);
}
Where NinjectHelper is a static helper class to get the Kernal from.
Since the membership collection and the Membership.Provider instance are created before Ninject can instantiate them, you need to perform post creation activation on the object. If you mark your dependencies with [Inject] for your properties in your provider class, you can call kernel.Inject(Membership.Provider) - this will assign all dependencies to your properties.
I haven't used Ninject ever.
but in StructureMap i set this dependency:
expression.For<MembershipProvider>().Add(System.Web.Security.Membership.Provider);
and it works fine.