I have a feeling this is just a misunderstanding on my part of DI in winforms.
I'm trying to implement Ninject into an existing winforms app. In Program.cs I am doing something similar to
IKernel kernel = new StandardKernel(new NinjectBindings());
Application.Run(kernel.Get<MainContainer>());
My NinjectBindings has
Bind<IFilterEngine>().To<FilterEngine>();
Then in a customer usercontrol (SearchResults.cs) in a form of the MainContainer form I am trying to use method injection like so
[Inject]
public void AddFilterEngine(IFilterEngine filterEngine)
{
_filterEngine = filterEngine;
}
The app compiles and runs fine however, my _filterEngine instance is null and the AddFilterEngine method is never called. Is this because SearchResults is not created with Ninject? It is hardcoded in its parent form. If so, I'm assuming every parent from this point needs to also be created with Ninject?
Injection only occurs when the instance is created through Ninject, i.e. by calling Kernel.Get<T>(), which is usually only done at the "topmost" point within your application or by Ninject creating this instance itself.
So unless you create your usercontrol by calling Kernel.Get<SearchResult>() (assuming the class is called SearchResult) using self-binding or by the container (as a constructor argument for example), your method will never get invoked, unfortunately.
You need to either use a field or a Property setter for Ninject to Inject your value on object creation.
[Inject]
public IFilterEngine FilterEngine { get; set; }
You can also pass it as a parameter to the constructor if you don't what this property to be public. This is the preferred method. Follow the examples on the Ninject website.
Related
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.
I am writing a console app in .Net core. I want to use dependency injection. My architecture is like this. Program contains a TradeProcessor (which does all the work) which in turn makes some CompoundTrades. I have got DI passing some classes into the TradeProcessor via its constructor and that whole ServiceProvider setup. That works fine.
Now, if i want to DI some classes into the CompoundTrade does the TradeProcessor have to pass them in via the constructor? I was under the impression that if you register the class to be constructed, all the classes you want to pass in, then they all got passed in "under the hood". You call CompoundTrade () but the other constructor gets called. Am i confusing that with DI in Asp.Net? What is the best design pattern for doing this? Stick all the ServiceProviders in a static class?
You call CompoundTrade() but the other constructor gets called.
That's not how dependency injection works. If you call a constructor explicitly, you get exactly that constructor.
You will need to reference you container and tell your container to create an instance of that class for you.
If you have an instance that needs to dynamically create new objects that are registered in the container, you will need to pass in the container and then use that to create those new objects. Don't call a constructor directly.
public TradeProcessor(IServiceProvider provider)
{
// save the provider in a field
}
public void ThisNeedsADynamicallyCreatedContainerObject()
{
if(condition)
{
var instance = this.provider.GetService<ICompoundTrade>();
}
else
{
var instance = this.provider.GetService<ISingleTrade>();
}
}
Disclaimer: actual syntax may vary depending on the dependency injection provider you use.
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.
Can anyone provide an all-around, method injection example using Autofac?
I have checked the documentation, but I find it hard to understand how this works and how the method is resolved.
So, OK, it is pretty straightforward how to register everything, but how can I use it? For example, I'd like to have a method which gets an HttpContext injected. So, having something like this:
builder
.Register<MyObjectType>()
.OnActivating(e => {
var dep = new HttpContextWrapper(HttpContext.Current);
e.Instance.SetTheDependency(dep);
})
.InstancePerRequest();
Note: This is possible with constructor injection but I'd like to understand the method injection way.
Question is how to use the resolved instance? Is it possible using the method injection to get a result back by the method which receives the dependencies? The behavior is not anywhere near the parameter injection but somehow close to property injection?
Update
#fknx essentially answers my question, by saying:
Method injection simply means that your dependency is not passed as a
constructor parameter or directly assigned to a property, but that it
is set using a (setter) method instead
So, if I decide to use method injection, the method essentially is behaving like a setter (kinda like the Java setter methods), so it is possible to use this dependency throughout the class entity?
What is the reason to do that and how it benefits from property injection?
Here you can find a small example to get you started:
using System;
using Autofac;
public class Program
{
public static void Main()
{
var builder = new ContainerBuilder();
builder.RegisterType<MyService>()
.OnActivating(e => e.Instance.SetMyDependency(new MyDependency()));
var container = builder.Build();
container.Resolve<MyService>();
}
}
public class MyService
{
private MyDependency _myDependency;
public void SetMyDependency(MyDependency myDependency)
{
_myDependency = myDependency;
Console.WriteLine("SetMyDependency called");
}
}
public class MyDependency
{
}
As stated in the documentation you can also call the method in the lambda expression which creates your service instance, if you are using Register instead of RegisterType.
but I find it hard to understand how this works and how the method is resolved.
This sounds a bit odd. Method injection simply means that your dependency is not passed as a constructor parameter or directly assigned to a property, but that it is set using a (setter) method instead.
I've created a .NET Fiddle so that you can check out the example.
Update
So, if I decide to use method injection, the method essentially is behaving like a setter (kinda like the Java setter methods)
Yes this is true.
so it is possible to use this dependency throughout the class entity?
This is also true, but this also holds for constructor injection if you store your dependency in a (readonly) field or property, and it is always the case for property injection.
What is the reason to do that and how it benefits from property injection?
To be honest I've never used method injection in C#. I would guess that it is more common in Java if you want to set a field through the corresponding setter method. In C# you can do the same with property injection.
Maybe I would use method injection if setting the dependency would involve rather complex code that I don't want to put into the property's setter or into the constructor.
However, in most cases I would advice you to use constructor injection whenever possible and property injection when it is not for whatever reason (e.g. circular dependencies).
I am currently learning the MVVM pattern, and the tutorial I am following uses Unity for DI. I haven't really used DI in this way before and just wanted clarification of my thoughts on how this specific code works.
In the View I have:
private ViewModel vm;
[Dependency]
public ViewModel VM
{
set
{
vm = value;
this.DataContext = vm;
}
}
where the dependency attribute is telling Unity to inject here. The ViewModel constructor takes an IQuoteSource object which is registered with Unity as such:
IUnityContainer container = new UnityContainer();
RandomQuoteSource randomQuoteSource = new RandomQuoteSource();
container.RegisterInstance<IQuoteSource>(randomQuoteSource);
MainWindow window = container.Resolve<MainWindow>();
window.Show();
How exactly does this work, as I am never explicitly creating an object of the ViewModel using the property above. Is this all handled within Unity, if so how does it achieve this?
Thanks.
This doesn't have much to do with the MVVM pattern per se, other than the fact that the view's dependency on its ViewModel is resolved via dependency injection.
For how this works, it's pretty simple. There are 3 simple concepts for DI:
The first is declaring a dependency, where some object specifies that it depends on something, either via a constructor or a property (which was the case in your example, using the DependencyAttribute).
The second concept is registration, where you register an implementation of the dependencies your objects have (in your case, you registered an implementation of the IQuoteSource). Note that you didn't have to register the ViewModel, because it's not really an implementation of an interface that you depend on.
The third is what glues things together, which is resolving the dependencies, where you ask the container to resolve some type for you, and it goes and looks at what dependencies that object declared (in your case, you're resolving the MainWindow which has a dependency on the ViewModel), finds the right registered implementation and resolves it. This behavior cascades through the resolution of the graph of objects (which resolves the dependency of the ViewModel on the IQuoteSource).
Hope this helps :)
Is it MainWindow which the VM property belongs to? If not I'm assuming that resolving a MainWindow starts some sort of resolve cascade which at some point includes creating the object which has the VM property in your example.
Unity examines each object it has to resolve within the cascade for properties decorated with [Dependency], and creates an object of the dependent property type. When it creates objects like this it picks the constructor which has the most parameters it knows how to create, which is where your registration of IQuoteSource -> RandomQuoteSource comes in.