Using property injection instead of constructor injection - c#

Long story short, I'm trying to use ELMAH with MVC 2 and Ninject, and I need to use parameterless constructors. I created an initial post about it here: Using a parameterless controller constructor with Ninject?
I was advised to use property injection instead of constructor injection. So I moved from this:
public class DepartmentsController : Controller
{
private IDepartmentsRepository departmentsRepository;
public DepartmentsController(IDepartmentsRepository departmentsRepository)
{
this.departmentsRepository = departmentsRepository;
}
...
}
to this:
public class DepartmentsController : Controller
{
private IDepartmentsRepository _departmentsRepository;
[Inject]
public IDepartmentsRepository DepartmentsRepository
{
get { return _departmentsRepository; }
set { _departmentsRepository = value; }
}
...
}
But in my other controller functions, whether I try to access DepartmentsRepository or _departmentsRepository, I get an object reference not set to an instance of an object error when I try to access it.
Is there something else I need to do here?

I had a similar problem. Have a look at my questions: Using Ninject with Membership.Provider.
Basically when you initialise DepartmentsController you need to injectthis (i.e. your departments controller into your Ninject kernal. So its something like:
public class DepartmentsController : Controller
{
private IDepartmentsRepository _departmentsRepository;
[Inject]
public IDepartmentsRepository DepartmentsRepository
{
get { return _departmentsRepository; }
set { _departmentsRepository = value; }
}
public DepartmentsController()
{
NinjectHelper.Kernel.Inject(this);
}
}
Where NinjectHelper in this case gets the current Ninject Kernel.

Try something like this:
Global.asax.cs
protected void Application_Start()
{
DependencyResolver.SetResolver(
new MyDependencyResolver(
new StandardKernel(
new MyModule())));
//...
}
MyDependencyResolver.cs
public class MyDependencyResolver : IDependencyResolver
{
private IKernel kernel;
public MyDependencyResolver(IKernel kernel)
{
this.kernel = kernel;
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
}
MyModule.cs
public class MyModule : NinjectModule
{
public override void Load()
{
Bind<IDepartmentsRepository>().To<DepartmentsRepository>();
}
}

There could be 2 reasons for object reference not set exception.
1) Ninject does not know how to Bind IDepartmentsRepository to a concrete implementation of DepartmentsRepository ( I doubt that is the case though )
2) If you are trying to access DepartmentsRepository property in your controller's constructor, it will throw the exception (since Ninject is only able to inject Property Dependencies after the object is constructed).
Hope that helps.

As Daniel T. in the above comment posted, you should check out Ninject.Web.Mvc. If you use the NinjectHttpApplication in that project, it will autowire everything for you, so that when the NinjectControllerFactory constructs a new controller, it will call Inject() for you to fill the property injections.

An observation for anyone arriving here having problems "Using property injection instead of constructor injection" with Ninject even if not specifically with MVC Controllers.
Ninject will only identify the [Inject] attribute on a property and perform the property injection on classes that are being brought to life as part of a Ninject chain of DI.
If you are creating the object like this
var myObj = new MyObj();
Ninject doesn't know about the class instantiation and so won't know to perform any injection.
In the MVC world you can use
var emailer = DependencyResolver.Current.GetService<IEmailer>();

Related

Dependency Injection with required parameter [duplicate]

How do I combine constructor injection with "manual" constructor parameters? ie.
public class SomeObject
{
public SomeObject(IService service, float someValue)
{
}
}
Where IService should be resolved/injected by my DI container, and someValue should be specified. How do I mix the two?
Such constructs should be avoided whenever possible. Therefore, ask yourself: is this parameter really required as constructor argument? Or can SomeObject be replaced by a stateless one which is reused by everyone that depends on it by passing the parameter to the method you execute on the object?
e.g. Instead of
public class SomeObject
{
private float someValue
public SomeObject(IService service, float someValue)
{
this.someValue = someValue
}
public float Do(float x)
{
return this.Service.Get(this.someValue) * x;
}
}
use
public class SomeObject
{
public SomeObject(IService service)
{
}
public float Do(float x, float someValue)
{
return this.Service.Get(someValue) * x;
}
}
If it is required go for a factory:
public interface ISomeObjectFactory
{
ISomeObject CreateSomeObject(float someValue);
}
public class SomeObjectFactory : ISomeObjectFactory
{
private IKernel kernel;
public SomeObjectFactory(IKernel kernel)
{
this.Kernel = kernel;
}
public ISomeObject Create(float someValue)
{
return this.kernel.Get<ISomeObject>(WithConstructorArgument("someValue", someValue);
}
}
Preview:
Ninject 2.4 won't require the implementation anymore but allow
kernel.Bind<ISomeObjectFactory>().ToFactory(); // or maybe .AsFactory();
You really shouldn't try to use D.I. for this. You could come up with all types of wacky solutions, but they may not make sense down the road.
Our approach is to create a factory via D.I., and the factory's Create method would then build itself out using the passed in D.I. container. We don't have to use this pattern often, but when we do it actually makes the product much cleaner (since it makes our dependency graphs smaller).
Another approach - initialization in two steps (not ninject related, any DI framework):
public class SomeObject
{
private readonly IService _service;
public SomeObject(IService service)
{
// constructor only captures dependencies
_service = service;
}
public SomeObject Load(float someValue)
{
// real initialization goes here
// ....
// you can make this method return no value
// but this makes it more convienient to use
return this;
}
}
and usage:
public static class TestClass
{
public static void TestMethod(IService service)
{
//var someObject = new SomeObject(service, 5f);
var someObject = new SomeObject(service).Load(5f);
}
}
I am not sure this is a good practice, but it could be solved in a different way, If you create an interface for the parameters, then a class that implements the interface with the values that you need (or fetch from somewhere). That way DI works with those parameters as well.
interface ISomeParameters
{
public float SomeValue { get; set; }
}
class SomeParameters : ISomeParameters
{
public float SomeValue{ get; set; } = 42.0;
}
services.AddSingleton(ISomeParameters, SomeParameters)
public MyService(IService service, ISomeParameters someParameters)
{
someParameters.SomeValue
...
I would probably use a naive solution to this. If you know the value of someValue when you need it I would remove it from the constructor and add a property to your object so you can set someValue. This way you can get your object from your container and then set the value when you have the object.
My other suggestion is that you instead of accessing it directly you create a factory that you can use to create such object. Then you register the factory in your container and use the factory to create your instance. Something like this:
public class SomeObjectFactory : ISomeObjectFactory
{
private IYourService _service;
public SomeObjectFactory(IYourService service)
{
_service = service;
}
public ISomeObject Create(float someValue)
{
return new SomeObject(_service, someValue);
}
}
you could try a pattern like that.
UPDATE: Updated the code to reflect improvement comments.
If 'somevalue' is always constant then you can think of using InjectionParameters while you are register your type with the container as it explained in the below post
See Here
but if that is not true, than there is no way to sepcify a parameter value while resolving a instance , you may think of moving the 'someValue' from the constructor and make it a property of the class.
In NInject, which you have tagged this with, you inject an automatically-generated Factory in the form of a Func<parameters you wish to feed in,T>, using the FuncModule as described in this post.
This approach is also available in autofac for one.
The various Factory method approaches are covered in the answers to this question.
EDIT: NB While this may be entertaining, please use #Remo Gloor's solution (and critically the advice re avoiding a solution of this nature)
Isn't this exactly what DI\Container::make() is for?
$object = $container->make(SomeObject::class, ['someValue' => 0.1]);

How to inject instance with [Dependency] attribute using Unity?

I am using Unity for dependency injection in ASP.NET C#.
Normally I would inject dependencies in the constructor, like:
class MyClass
{
private readonly ISomething _something;
public MyClass(ISomething something)
{
_something = something;
}
public MyMethod()
{
// _something is instantiated as expected
}
}
where the dependency has been configured as:
container.RegisterType<ISomething, Something>();
That's all great.
But now I need to do an injection without the use a constructor. So I read that I can use the dependency attribute [Dependency] for this purpose.
class MyClass
{
[Dependency]
private ISomething _something { get; set; }
public MyMethod()
{
// _something appears to be null
}
}
But for some reason _something appears to be null.
What am I missing?
SOLUTION:
See the accepted answer over here, which shows how to create a factory to generate the injected instance:
How to resolve dependency in static class with Unity?
Worked for me!
You are trying to inject into a private property. This is not possible.
And personally, I suggest you stick to constructor injections to prevent locking yourself into a specific Dependency Injection framework.

Filter constructor injection using Ninject

I am trying to find a way to use Ninject to inject constructor dependencies into filters. I am finding many articles describing property injection which is now advised against, but the remainder of articles involve complex setups with factories, locators, global wrappers or stub attributes.
With MVC allowing you to override almost any part of it's operation I would have thought it would be simply a case of creating your own filter provider in a similar fashion to how you create your own dependency resolver.
What is the now correct way to allow injection, or does it become easier if you use certain types of filters vs others?
public class UserValidationAttribute : ActionFilterAttribute
{
private IRepository repository;
public UserValidationAttribute(IRepository repository)
{
this.repository = repository;
}
}
There is a way to use constructor injection.
First you replace your attribute with an 'empty' one which you will just use as a marker
public class UserValidationAttribute : Attribute { }
Then you create a filter class as an IActionFilter.
public class UserValidationFilter : IActionFilter
{
private readonly IRepository repository;
public UserValidationFilter(IRepository repository)
{
this.repository = repository;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
//do something
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
//do something
}
}
Then you can register it with something like
private static void RegisterServices(IKernel kernel)
{
kernel.BindFilter<UserValidationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<UserValidationAttribute>();
}
If your attribute itself has constructor parameters, you can pass them in like
kernel.BindFilter<UserValidationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<UserValidationAttribute>();
.WithConstructorArgumentFromActionAttribute<UserValidationAttribute>("myParameter", attr => attr.MyParameter);
The BindFilter syntax is part of Ninject.Web.Mvc.FilterBindingSyntax.
Assuming that the attribute is to be a part of the metadata, which means that it should be instantiated at the compile time, it is not possible to have a repository injected into an attribute by any ioc container. Containers operate in run time.
If you want to inject dependencies to a filer, you want to use property injection instead of constructor injection.
public class UserValidationAttribute : ActionFilterAttribute
{
[Inject]
private IRepository repository { get; set; }
public UserValidationAttribute()
{
}
}
https://stackoverflow.com/a/7192754/296861

Ninject - how to inject during object lifetime?

I'm just getting started with dependency injection. I've read the Ninject wiki and its very clear on how to inject dependencies where a single instance of the dependency is required, using constructor, property or method injection. But how do you handle the case where your class needs to construct objects during its lifetime (after construction)? For example:
class AddressBook
{
private List<IContact> _contacts;
public AddContact(string name)
{
_contacts.Add(****what?****)
}
}
The only way I can think is to use constructor injection to pass in an IKernel and use that to get our IContact:
class AddressBook
{
private IKernel _kernel;
private List<IContact> _contacts;
public AddressBook(IKernel kernel){ _kernel = kernel; }
public AddContact(string name)
{
_contacts.Add(_kernel.Get<IContact>(new Parameter("name", name)));
}
}
But then how can you actually inject the kernel? What mapping would be required? Is this even the right approach?
Thanks for any help
felix
Similar to what the others have answered, we use a generic IFactory interface:
public interface IFactory<T>
{
T Get();
}
Which can be used like this:
public AddressBook(IFactory<IContact> ContactFactory)
And then implemented like this:
public class InjectorFactory : IFactory<T>
{
// we wrapped the Kernel in an Injector class
public T Get() { return Injector.Get<T>(); }
}
And bound like this:
Bind(typeof(IFactory<>)).To(typeof(InjectorFactory<>))
It has worked very well for us so far.
The answer as suggested by Benjamin Podszun:
Inject a factory:
public interface IContactFactory
{
IContact CreateContact(string name);
}
class AddressBook
{
private IContactFactory _factory;
private List<IContact> _contacts;
public AddressBook(IContactFactory factory){ _factory = factory; }
public AddContact(string name)
{
_contacts.Add(_factory.CreateContact(name));
}
}
Then you can bind the factory to whatever you want to create any specific instance of IContact.
You can do it pretty cleanly with: (exec summary of another answer re a slightly different question)
Bind<Func<IContact>>().ToMethod( context => () => Kernel.Get<Contact>() );
Your other options are:
have an IKernel injected as you did (that's supported OOTB with any special tricks), but as you allude to, this is rarely what you want - that's tantamount to Service Location.
Do a full-scale factory. See the other answer for the idiomatic Ninject way (a provider) to do more or less what your answer-to-self says. You better have a good reason to do that amount of boiler plate though.

How to Inject daoFactory into NHibernate EventListener

I need to Inject some global service (daoFactory) into EventListenet subscribed on PostUpdate event. I`ve read that it is possible to do this way:
public class YourPostInsertListener : IPostInsertEventListener
{
private readonly IPersistentAuditor auditor;
public YourPostInsertListener(IPersistentAuditor auditor)
{
this.auditor = auditor;
}
public void OnPostInsert(PostInsertEvent #event)
But this code just throws exception: no parameterless constructor was specified for EventListener. And this is understandable behavior, because I haven`t added my service to any container. So how can I specify the IoC contauner in NHibernate?
The IoC that I've been using is Ninject. The best way I found so far is to take advantage of the ServiceLocator provdided by the Microsoft Patterns and Practices guys:
internal class YourPostInsertListener : IPostInsertEventListener
{
IKernel Kernel
{
get
{
return ServiceLocator.Current.GetInstance<IKernel>();
}
}
IPersistentAuditor
{
get
{
return Kernel.Get<IPersistentAuditor>();
}
}
// ... Rest of class
}
In the class that sets up your IoC container you would do this:
ServiceLocator.SetLocatorProvider( () => new NinjectServiceLocator( kernel ) );

Categories

Resources