Is it possible to have Unity search any child containers if a resolution fails? - c#

I have a unity container with a number of registrations. I then create a child container and add some more registrations. The child container is meant to contain a specific group of registrations that have a different lifetime than those in the parent container and the child container may be disposed of at any time.
Now when I try to resolve a class which has some constructor dependencies from the parent container and some from the child container, the resolution fails since it cannot find any of the dependencies that are defined in the child container.
Is there any way, via some unity extension or something, that I can have the resolution call attempt to search child containers if it fails on the parent container?
For example:
//Some class that setups up unity
class Init()
{
...
_container.RegisterType<ICar, BMW>(new ContainerControlledLifetimeManager());
var childContainer = _container.CreateChildContainer();
_childContainer.RegisterType<IPlane, Boeing>(new ContainerControlledLifetimeManager());
...
}
class TestClass
{
//Fails because only ICar is able to be resolved
public TestClass(ICar car, IPlane plane){...}
}
What I am trying to achieve is to have singleton types that are registered that I can dispose of when I choose to (for example when a view is closed). So first thing that came to mind was to group those types in a child container with ContainerControlledLifetimeManager and then I can dispose of the container as I see fit, leaving the ones that I still want to keep untouched in the parent container. Perhaps there is a better approach but I am not sure.

Related

Integrating Unity Container into existing WinForms app: injection and child forms questions

I have an existing 90k+ line Winforms application that I am trying to refactor, add unit testing to, add dependency injection to, and eventually get it over to an MVC architecture.
And so I'm trying to figure out how to use Unity Container with Winforms and get it going with at least injecting some dependencies that represent some Data Access Layer classes (mostly remote REST services).
Some bits of code regarding where I'm at:
Over in my Program.cs:
private static UnityContainer container;
public static void Main()
{
container = new UnityContainer();
container.RegisterType<IIncidentDataService, IncidentQuery>();
container.RegisterType<IRuleService, RulesQuery>();
Application.Run(container.Resolve<MainForm>());
}
Over in my MainForm.cs:
public partial class MainForm: Form
{
private IIncidentDataServcie incidentDataService;
private IRuleService ruleService;
// constructor
public MainForm(IIncidentDataService passedIncidentDataService, IRuleService passedRuleService)
{
this.InitializeComponent();
incidentDataService = passedIncidentDataService;
ruleService = passedRuleService;
}
<lots more code>
}
I realize I'm not doing this quite right yet. Certainly, I don't want to have to pass more and more parameters to the constructor on MainForm, as I have several other services yet to pass.
Now, one of the reason I have several other services to pass is that MainForm has controls on it that are used to summon child forms... and I'll need to pass service objects / dependencies over to those.
So, how SHOULD I be passing a container of multiple dependencies over to this Windows form?
I get the feeling I should be making one single object out of all of these service-classes... and passing that alone instead.
Application.Run(container.Resolve<MainForm>());
I realize I'm not doing this quite right yet.
To the contrary, this is as perfect as it gets.
Your keyword is factory - if MainForm needs to create an instance of SomeControl (that may have dependencies itself), inject an ISomeControlFactory (that has a SomeControl Create(); method) into MainForm.
Copying this answer:
For dependencies that are independent of the instance you're creating, inject them into the factory and store them until needed.
For dependencies that are independent of the context of creation but need to be recreated for each created instance, inject factories into the factory and store them.
For dependencies that are dependent on the context of creation, pass them into the Create method of the factory.

Ninject won't resolve constructor injection in WPF

My WPF desktop application is attempting to use Ninject to inject some interface dependencies as follows. The app startup looks like this, (I think) auto-generated:
void App_Startup(object sender, StartupEventArgs e)
{
IKernel _Kernel = new StandardKernel();
_Kernel.Load(Assembly.GetExecutingAssembly());
}
I then have a NinjectModel-extending class whose Load method gets called by the above, and binding takes place like so:
Bind<Inheritance.IWindowProvider>().To<WindowProvider>().InSingletonScope();
My view models then take in an IWindowProvider and in this case I've also added the [Inject] attribute.
[Inject]
public LoginDetailsVM (IWindowProvider windowProvider) {
this.WindowProvider = windowProvider;
}
Elsewhere then (in another VM), I want to make an instance of this view model:
IKernel kernel = new StandardKernel();
LoginDetailsVM loginDetails = kernel.Get<LoginDetailsVM>();
However I get the "dreaded" error:
Error activating IWindowProvider
No matching bindings are available,
and the type is not self-bindable.
My initial search turns up that me instantiating StandardKernel twice is probably the issue, but I'm not sure how to access it otherwise.
Surely having to pass around an instance of the kernel somewhat defeats one of the points of having the injection?
Also, is the explicit Get<T>() form the accepted choice for obtaining instances, or is there a better implicit method of calling an injected constructor?
Apologies for what might seem a naive understanding here, I'm totally new to Ninject and DI generally.
The problem isn't passing around the kernel - it's where you're accessing it. If you're referencing it outside of your composition root (App_Startup) then creating a new one isn't any better than passing around the one you already created.
When you need to resolve something outside of your composition root and you don't want to reference the container, one solution is to create a factory. Your component that needs to resolve something doesn't ask the container for it - it asks the factory for it.
The factory, in turn, is set up to resolve it from the container. But that's set up in your composition root, and the factory could be replaced with an implementation that doesn't involve the container. So you can still say that your component doesn't depend on or talk to the container.
Here's some documentation on configuring Ninject to supply an instance to a factory.
Think of an IOC container like a magic dictionary with type and object instances stored in it.
If you did
Void a method (){
Var dictionary = new dictionary ();
dictionary.Add(typeof(IFOO), new Foo());
}
Void other_method(){
Var dictionary = new dictionary ();
IFOO instance =Dictionary[typeof(IFOO)];
// would you expect this to work?
}
Often the singleton pattern is used to provide access to an IOC container.

Ioc/DI - How to use the registered dependencies?

I think I'm missing a key part of how to actually use IoC/DI. I happen to be using the Unity container. I know how to setup a class to have it's dependencies injected and I also know how to make Unity register a type.
But what I don't know is how to actually then make use of these registrations.
So for example:
var container = new UnityContainer();
container.RegisterType<IRepository, XmlRepository>();
var service = new MyService(container.Resolve<IRepository>());
public interface IRepository
{
void GetStuff();
}
public class XmlRepository : IRepository
{
public void GetStuff()
{
throw new NotImplementedException();
}
}
public class MyService
{
private readonly IRepository _myRepository;
public MyService(IRepository repository)
{
_myRepository = repository;
}
}
Here I have a service layer which accepts a parameter of type IRepository. It's the container part that I seem to not be understanding.
Isn't the point of IoC/DI to be able to not have to manually resolve types every time I need to create an instance? In my code I'm getting the container to resolve a type, unless I'm misunderstanding how this is supposed to work, isn't the container supposed to somehow automatically (with reflection?) inject the dependency I told it to use when I registered the type? var service = new MyService(...) Is calling container.Resolve the correct way of doing this?
I've created a container, but how do I share this container amongst my project/code? This sort of relates to the first question. I had previously thought that there was a single place that you register types. So far the only way I can see how to get around this is to:
Keep registering types wherever I use them and end up with duplicated code
Pass the container around to every place I'm going to be resolving types
Neither of these ways are how I'd expect this to work
Isn't the point of IoC/DI to be able to not have to manually resolve types every time I need to create an instance?
No, that's the point of a DI Container, but there are drawbacks to using a container as well. Favour Pure DI over using a DI Container, as this will teach you how to use Dependency Injection using only first principles.
I've created a container, but how do I share this container amongst my project/code?
You don't. The DI Container should only be used in the Composition Root (if you use a DI Container at all).
Put your container setup in a module that runs when your program starts. You can call it from Main, for example. This is called a boot strapper.
See Dependency Injection with Unity for a good example of how to do this.
You don't need to do new MyService(container.Resolve<IRepository>()). To get an instance of MyService, just use container.Resolve<MyService>(); it will automatically resolves the dependencies for MyService.

Sharing scope while dynamically resolving dependencies

I have a situation where a class (Parent) has a dependency (IScopedInstance) and also resolves an other interface (IOtherDependency) dynamically inside a method. The implementation of that interface (Dependency) has the same dependency as the original class. I want that instance to be scoped to the instance of Parent ie: I want the same instance inside Parent and Dependency, but only if the dependency was resolved from inside Parent I'm using Castle.Windsor as DI-container.
public class Parent : IParent
{
public Parent(IScopedInstance instance)
{
}
public void DoSomething()
{
var anotherDependency = container.Resolve<IOtherDependency>();
}
}
public class Dependency : IOtherDependency
{
public Dependency(IScopedInstance instance)
{
}
}
This works when IOtherDepedency is injected into the constructor of Parent:
container.Register(Component
.For<IScopedInstance>()
.ImplementedBy<ScopedInstance>()
.LifestyleBoundTo(x => x.First(xx =>
xx.ComponentModel.Implementation.InheritsOrImplements(typeof(IParent)))));
But understandably it doesn't work when resolving it from inside the method, since there's no IParent in the dependency graph (it's a new graph).
The real use case is a bit different and I don't directly resolve the IOtherDependency inside the method, but I removed all the extra info that's not needed.
Any idea how to do this?
First of all you shoul a factory, most likely a typed factory, within you method in order to get an instance from the container.
I guess a scoped lifestyle should fit your needs, or a perwebrequest lifestyle if you code is running in a web app.

Require dependency per method call from UnityContainer

So in my current code i'm working on some sort of notification manager.
The idea is that my main BL will use this notification manager per method call. Hence there will probably only be one notification manager (singleton in unity i guess).
When you use the notification manager you can send a notification via SMS\Email\Other. what actually happens is that the notification manager resolves a "INotificationProvidor" which also resides in unity container. This resolve is done by name as in "SMS", "Email", "Other".
Here is a little code snippet:
var notificationProvidor =
m_Container.Resolve<INotificationProvidor<TResult>>(
typeOfNotification.ToString());
ResultMessage<TResult> notificationResult = notificationProvidor
.SendNotification(source, destination, message, subject);
As you can see the notification manager holds an instance of the container to resolve each one of the "INotificationProvidor"s.
How can i possible remove this need of holding the container in the notification manager? with the following restrictions:
Not all types of "INotificationProvidor"'s (SMS,email,other) might be registered in the container.
There will be only one notification manager. (since BL using it will be alive during the course of the application and would receive it from DI)
In short...resolving dependency per method call. :)
I would use Factory pattern. Either create your own with your own interface and implementation. Or I believe many IoC frameworks are clever, when you try to resolve Func<string, INotificationProvidor<TResult>>, they will create the factory method dynamicaly by themselves.
The actualy factory implementation would probably need reference to the container itself, but there is no need for this implementation to be part of your project. It can be part of project, where refference to container is no problem.
I suggest the only way to do it is to use some sort of factory, to resolve INotificationProvider instead of Unity container, in any case you have to hold a reference to something, that will resolve dependencies in runtime.
Here's the factory's interface:
interface IProvidersResolver
{
INotificationProvider<TNotification> Resolve<TNotification>();
}
That's how you can use it in NotificationManager:
// here you hold the reference to the resolver
private IProvidersResolver _resolver;
// here you use injected factory to resolve INotificationProvider
void UseResolver()
{
INotificationProvider<SomeNotification> provider = _resolver.Resole<SomeNotification>();
}
So you hold a reference to IProviderResolver (the factory) only. This is the common practice. Alternatively you can:
instantiate NotificationManager for every INotificationProvider<TNotification>
pass a reference to the container into NotificationManager
I think you can solve this by having a dependency on an factory which will turn the typeOfNotification into an actual NotificationProvider in the classes which need to be able to get a NotificationPrivider based on a sting. The factory class will get created by the container, and have all of the available notification providers injected into its constructor.
Then you can have the container do all the wiring up for you in the composition root, but have each method get a NotificationProvider based on the string value of typeOfNotification

Categories