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.
Related
I have a class (MyFacade) that I injected parameter(s) with Ninject:
class MyFacade
{
IDemoInterface demo;
public MyFacade(IDemoInterface demo)
{
this.demo = demo;
}
public void MyMethod()
{
Console.WriteLine(demo.GetInfo());
}
}
Of course, I have to setup the Ninject to inject the appropiate implementation of my parameter (IDemoInterface)
I know, I can instantiate MyFacade object by doing kernel.Get<MyFacade>(); without setting anything else. Currently my facade doesn't have an interface (because it is my only implementation, maybe I will add its interface for standard proposes)
if I want to make this facade singlenton, I know two ways: create a empty constructor and pass a parameter by doing this kernel.Get<IDemoInterface>(); or by setup Ninject like: kernel.Bind<MyFacade>().To<MyFacade>().InSingletonScope();
The second one look a better approach, but do you know any other way to setup it in a singleton way?
When setting up your bindings, you need to bind your dependencies. It is always better to setup your dependencies in your bindings, as opposed to doing a kernel.Get<T>() in a constructor. You are using IOC, so leverage the framework you are using to do the injection for you.
In your second example binding, what you are missing is binding in your IDemoInterface. Your bindings should look like this:
//bind the dependency to the implementation.
kernel.Bind<IDemoInterface>().To<DemoInterface>();
//since you bound your dependency, ninject should now have
// all the dependencies required to instantiate your `MyFacade` object.
kernel.Bind<MyFacade>().To<MyFacade>().InSingletonScope();
If you do not want the container to manage the lifecycle of your singleton by using InSingletonScope(), but still wants it to get injected, I can think of 2 ways to go about it. Choose which one suits better to your needs. Consider the following ISingleton (name your interface) implementation:
public class ConcreteSingleton : ISingleton
{
private static readonly Lazy<ConcreteSingleton> _instance = new Lazy<ConcreteSingleton>(() => new ConcreteSingleton());
private ConcreteSingleton() { }
public static ConcreteSingleton Instance
{
get
{
return _instance.Value;
}
}
}
Alter the singleton class to have a GetInstance(...) method
In this method (my preferred approach), you won't be calling kernel.Inject(instance) each time, only for the first time the singleton is initialized. Adding the following method to your ConcreteSingleton class:
public static ConcreteSingleton GetInstance(IKernel kernelForInjection)
{
if (_instance.IsValueCreated == false)
{
kernelForInjection.Inject(_instance.Value);
}
return _instance.Value;
}
And using this binding:
kernel.Bind<ISingleton>().ToMethod(c => ConcreteSingleton.GetInstance(c.Kernel));
Will achieve the desired behavior of not having a public constructor but enabling your facade to be efficiently injected.
Perform injection each time the ISingleton instance is requested
If by any reason you are not allowed to modify your ConcreteSingleton: This approach will wrap the singleton creation in a provider to efficiently inject the instance only for the first time it is created. It is important to note that the provider itself must be registered as a singleton.
internal class ConcreteSingletonProvider : Provider<ISingleton>
{
public IKernel Kernel { get; set; }
//Just a wrapper
private readonly Lazy<ISingleton> _lazy = new Lazy<ISingleton>(() => ConcreteSingleton.Instance);
public ConcreteSingletonProvider(IKernel kernel)
{
Kernel = kernel;
}
protected override ISingleton CreateInstance(IContext context)
{
if (_lazy.IsValueCreated == false)
{
Kernel.Inject(ConcreteSingleton.Instance);
}
return _lazy.Value;
}
}
And your bindings should be like this:
kernel.Bind<ISingleton>().ToProvider<ConcreteSingletonProvider>();
kernel.Bind<ConcreteSingletonProvider>().ToSelf().InSingletonScope();
This gist has a complete working sample for the above approach.
Hope that helps!
I am trying to avoid the anti-pattern of Container.Resolve(). How do I change the following to use contructor injection?
Installers.cs
public void Install(Castle.Windsor.IWindsorContainer container,
Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
{
container.AddFacility<TypedFactoryFacility>();
container
.Register(Component.For<IData>()
.ImplementedBy<Data>().LifeStyle.Singleton)
}
BootStrapper.cs
public class Bootstrapper
{
private static volatile IWindsorContainer _theWindsorContainer;
private static object syncRoot = new Object();
public static IWindsorContainer Container
{
get
{
if (_theWindsorContainer == null)
{
lock (syncRoot)
{
if (_theWindsorContainer == null)
{
_theWindsorContainer = new WindsorContainer().Install(FromAssembly.This());
}
}
}
return _theWindsorContainer;
}
}
}
OViewModel.cs
public IData ThisData {get;set;}
public OViewModel()
{
ThisData= Bootstrapper.Container.Resolve<IData>();
InitializeComponent();
}
How do I use Windsor Castle constructor injection to initialize the viewmodel and do constructor injection? Either InitializeComponentdoesn't get called or ThisData is null.
I wrote an article a few years ago about integrating Castle Windsor into WPF to achieve DI in your view models. It might be what you're looking for.
I'm not familiar with the particulars of Castle Windsor, but typically you would structure your OViewModel like this:
public class OViewModel
{
public IData ThisData { get; set; } //private set??
public OViewModel(IData _thisData)
{
ThisData = _thisData;
InitializeComponent();
}
}
That would be constructor injection. You can search for the term parameter injection for other ways of getting it done.
But basically the when an OViewModel is resolved by the container, it knows how to resolve an IData and will automatically resolve it for you.
Of course, this just backs things up -- whatever is creating the OViewModel needs to use container.Resolve and you don't want to do that. So you'll probably inject the view model (or an interface of it) (or a factory object) to that parent object. And so on back up the chain until you have single object that is the root of your application that you need to resolve from the container to get everything started.
Hopefully someone with more knowledge of the particulars of Castle Windsor can give you more details.
In my NinjectWebCommon.cs file, under the RegisterServices method I have the following:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IProfileRepository>().To<ProfileRepository>();
kernel.Bind<IMatchUpService>().To<MatchUpService>();
kernel.Bind<ISoloUserRepository>().To<SoloUserRepository>();
SignalR.GlobalHost.DependencyResolver = new SignalR.Ninject.NinjectDependencyResolver(kernel);
}
I am trying to inject SoloUserRepository into my hub class, here is my hub class:
public class MatchMaker : Hub
{
[Inject]
private ISoloUserRepository soloUsers { get; set; }
}
For some reason when I try to use the soloUsers object in my Hub class, i get object reference not set to instance of an object because the soloUsers object is never being instantiated or, in other words, not injected. Am I doing something wrong?
Your problem is that you have a private property, and Ninject by default doesn't inject private properties.
So either you make your property public or you can enable non public property injection with:
kernel.Settings.InjectNonPublic = true;
I'm not familiar with the dependency injection in SignalR (so maybe it's not supported) but you should always prefer constructor injection so your Hub should be like:
public class MatchMaker : Hub
{
private readonly ISoloUserRepository soloUsers;
public MatchMaker(ISoloUserRepository soloUsers)
{
this.soloUsers = soloUsers;
}
}
I have the IRespository registered twice (with names) in the following code:
// Setup the Client Repository
IOC.Container.RegisterType<ClientEntities>(new InjectionConstructor());
IOC.Container.RegisterType<IRepository, GenericRepository>
("Client", new InjectionConstructor(typeof(ClientEntities)));
// Setup the Customer Repository
IOC.Container.RegisterType<CustomerEntities>(new InjectionConstructor());
IOC.Container.RegisterType<IRepository, GenericRepository>
("Customer", new InjectionConstructor(typeof(CustomerEntities)));
IOC.Container.RegisterType<IClientModel, ClientModel>();
IOC.Container.RegisterType<ICustomerModel, CustomerModel>();
But then when I want to resolve this (to use the IRepository) I have to do a manual resolve like this:
public ClientModel(IUnityContainer container)
{
this.dataAccess = container.Resolve<IRepository>(Client);
.....
}
What I would like to do is to have it resolved in the constructor (just like IUnityContainer). I need some way to say which named type to resolve to.
Something like this: (NOTE: Not real code)
public ClientModel([NamedDependancy("Client")] IRepository dataAccess)
{
this.dataAccess = dataAccess;
.....
}
Is there a way to make my fake code work?
You can configure dependencies with or without names in the API, attributes, or via the config file. You didn't mention XML above, so I'll assume you're using the API.
To tell the container to resolve a named dependency, you'll need to use an InjectionParameter object. For your ClientModel example, do this:
container.RegisterType<IClientModel, ClientModel>(
new InjectionConstructor( // Explicitly specify a constructor
new ResolvedParameter<IRepository>("Client") // Resolve parameter of type IRepository using name "Client"
)
);
This tells the container "When resolving ClientModel, call the constructor that takes a single IRepository parameter. When resolving that parameter, resolve with the name 'Client' in addition to the type."
If you wanted to use attributes, your example almost works, you just need to change the attribute name:
public ClientModel([Dependency("Client")] IRepository dataAccess)
{
this.dataAccess = dataAccess;
.....
}
This is a very late response but the question still shows up in Google.
So anyways, 5 years later...
I have a pretty simple approach. Usually when you need to use "named dependency" it's because you're trying to implement some kind of strategy pattern. In that case, I simply create a level of indirection between Unity and the rest of my code called the StrategyResolver to not be directly depending on Unity.
public class StrategyResolver : IStrategyResolver
{
private IUnityContainer container;
public StrategyResolver(IUnityContainer unityContainer)
{
this.container = unityContainer;
}
public T Resolve<T>(string namedStrategy)
{
return this.container.Resolve<T>(namedStrategy);
}
}
Usage:
public class SomeClass: ISomeInterface
{
private IStrategyResolver strategyResolver;
public SomeClass(IStrategyResolver stratResolver)
{
this.strategyResolver = stratResolver;
}
public void Process(SomeDto dto)
{
IActionHandler actionHanlder = this.strategyResolver.Resolve<IActionHandler>(dto.SomeProperty);
actionHanlder.Handle(dto);
}
}
Registration:
container.RegisterType<IActionHandler, ActionOne>("One");
container.RegisterType<IActionHandler, ActionTwo>("Two");
container.RegisterType<IStrategyResolver, StrategyResolver>();
container.RegisterType<ISomeInterface, SomeClass>();
Now, the nice thing about this is that I will never have to touch the StrategyResolver ever again when adding new strategies in the future.
It's very simple. Very clean and I kept the dependency on Unity to a strict minimum. The only time I would have touch the StrategyResolver is if I decide to change container technology which is very unlikely to happen.
Hope this helps!
Edit: I don't really like the accepted answer because when you use the Dependency attribute in your service's constructor you actually have a hard dependency on Unity. The Dependency attribute is part of the Unity library. At that point you might as well pass an IUnityContainer dependency everywhere.
I prefer having my service classes depend on objects that I completely own instead of having a hard dependency on an external library all over the place. Also using Dependency attribute makes the constructors signatures less clean and simple.
Furthermore, this technique allows to resolve named dependencies at runtime without having to hardcode the named dependencies in the constructor, in the application configuration file or use InjectionParameter which are all methods that require to know what named dependency to use at design time.
Edit (2016-09-19):
For those that might wonder, the container will know to pass itself when you are requesting IUnityContainer as dependency, as shown in the StrategyResolver constructor signature.
Edit (2018-10-20):
Here's another way, simply using a factory:
public class SomeStrategyFactory : ISomeStrategyFactory
{
private IStrategy _stratA;
private IStrategy _stratB;
public SomeFactory(IStrategyA stratA, IStrategyB stratB)
{
_stratA = stratA;
_stratB = stratB;
}
public IStrategy GetStrategy(string namedStrategy){
if (namedStrategy == "A") return _stratA;
if (namedStrategy == "B") return _stratB;
}
}
public interface IStrategy {
void Execute();
}
public interface IStrategyA : IStrategy {}
public interface IStrategyB : IStrategy {}
public class StrategyA : IStrategyA {
public void Execute(){}
}
public class StrategyB : IStrategyB {
public void Execute() {}
}
Usage:
public class SomeClass : ISomeClass
{
public SomeClass(ISomeStrategyFactory strategyFactory){
IStrategy strat = strategyFactory.GetStrategy("HelloStrategy");
strat.Execute();
}
}
Registration:
container.RegisterType<ISomeStrategyFactory, SomeStrategyFactory>();
container.RegisterType<IStrategyA, StrategyA>();
container.RegisterType<IStrategyB, StrategyB>();
container.RegisterType<ISomeClass, SomeClass>();
This 2nd suggestion is the same thing but using the factory design pattern.
Hope this helps!
You should be able to use ParameterOverrides
var repository = IOC.Container.Resolve<IRepository>("Client");
var clientModel = IOC.Container.Resolve<ClientModel>(new ParameterOverrides<ClientModel> { {"dataAccess", repository } } );
edit:
I'm not sure why you're passing around the UnityContainer - personally, we inject our dependencies into the constructor themselves (which is "normal" from what I've seen). But regardless, you can specify a name in your RegisterType and Resolve methods.
IOC.Container.RegisterType<IRepository, GenericRepository>("Client");
IOC.Container.Resolve<IRepository>("Client");
and it will give you the type you registered for that name.
Don't do this - just create a class ClientRepository : GenericRepository { } and utilise the Type system.
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>();