How to Access ninject .Net Container across Application - c#

I am trying to implement a simple application with the MVVM pattern using Dependency Injection With ninject.
The recommended way of using DI is to resolve all dependencies at just one point:
App()
{
kernel = new StandardKernel();
kernel.Bind<IService>().To<DefaultService>();
kernel.Bind<IMainWindow>().To<MainWindow>();
// Register all other dependencies here
// resolve all dependencies.
MainWindow mw = kernel.Get<IMainWindow>();
}
This is a very ideal scenario where all dependencies get resolved by just one call to the kernel and the kernel is not needed any more in the application.
However the problem is that there are "Views" in my application that need to be resolved e.g in the MainViewModel by just knowing the type of some specific UserControl that is only known at runtime.
The easiest way and at the same time worse (not recommended) is to pass the container as injected parameter in the constructor and then simply call:
void resolveByType(Type viewType)
{
// Container was injected in this class (Dirty!!!).
Container.Get(viewType)
}
This works fine but I am wondering if there is a better way to achieve the same behaviour?

Related

AutoFac - InstancePerLifetimeScope becomes SingleInstance When Component Resolved as Dependency for Singleton

Original:
Summary:
I'm having an issue with Autofac, where objects which are registered as singletons/'SingleInstance', are having their dependencies that are registered as 'InstancePerLifetimeScope' are ending up becoming 'singletons' after the resolution of the first singleton is resolved.
Details: I'm working on a project to incorporate Autofac (version #4.9.2) into a windows service which is responsible for running background tasks. In preparation I've tried reading everything I can that involves lifetime scopes. My code has Autofac resolve service objects, where each service has it's own expected role and function, and/or sometimes interact with other services (currently there are no circular dependencies). To do this I'm registering these services as Singletons and then resolving/starting each in a sequential order. By registering services as Singletons, if another service has an dependency on a already resolved service, rather then instantiate a new service Autofac returns the already resolved one.
The problem I'm running into is, there are instances where services have dependencies that when resolved it's expected that the dependency will be reused across the whole service (my example is a logger). However, it's also expected that the resolved dependency should be different in each service, as each service's resolved dependency could have different behavior. To do this I was registering these dependencies as 'InstancePerLifetimeScope'. However, when the service is resolved, the service's dependency which is registered as 'InstancePerLifetimeScope' end up in Autofac's root container which is retrieved for all other services that share the same dependency rather then resolving the dependency as a new object.
Example: I've placed an simplified example below that's similar to my code that replicates and outlines how the problem is being hit.
// Use of AutoFac with Established Components
var builder = new ContainerBuilder();
// Register
builder.RegisterType<Logger>().As<ILogger>().InstancePerLifetimeScope();
builder.RegisterType<Service>().Named<IService>("first").SingleInstance();
builder.RegisterType<Service>().Named<IService>("second").SingleInstance();
// Build
var container = builder.Build();
// Resolve
IService firstService = null;
using (ILifetimeScope firstScope = container.BeginLifetimeScope())
{
firstService = firstScope.ResolveNamed<IService>("first");
};
IService secondService = null;
using (ILifetimeScope secondScope = container.BeginLifetimeScope())
{
secondService = secondScope.ResolveNamed<IService>("second");
};
// Test
// This case is false, both services are different
if (firstService == secondService)
{
throw new Exception("Services were the same");
}
// This case is true, each service shares the same logger
if (((Service)firstService)._logger == ((Service)secondService)._logger)
{
throw new Exception("Loggers were the same");
}
public interface ILogger
{
void Log(string message);
}
public interface IService
{
void Run();
}
public class Logger : ILogger
{
public Logger()
{
Console.WriteLine("Create: Logger");
}
public void Log(string message)
{
Console.WriteLine(message);
}
}
public class Service : IService
{
public readonly ILogger _logger;
public Service(ILogger logger)
{
Console.WriteLine("Create: Service");
_logger = logger;
}
public void Run()
{
Console.WriteLine("Run");
}
}
Conclusion: I'd expect that when an object is registered as a 'InstancePerLifetimeScope', it would always be tied to the current child scope regardless of if the object it is being resolved for is registered as a 'SingleInstance'. However, instead it seems the resolved dependency is being placed in to the root scope.
Is there anything I can do to enforce 'InstancePerLifetimeScope' registration dependencies to be exactly that for objects that are resolved for a 'SingleInstance', so these dependencies don't end up in the root container and reused by other services?
Edit 08/05/2019:
From John King link which points to the subject of Captive Dependencies, I've reviewed the topic and agree that my issue falls into the realm of Captive Dependencies. However, I am surprised by how the matter is handled, in that captive dependencies just exists as a known issue across all IOC libraries, and there seems to be little to no hope of discussing different solutions to mitigate the issue within a update. Despite that I still think the problem I'm hitting is a bit different from the examples outlined in Autofac's documentation and the other resources which AutoFac references for how this issue can occur. My reasoning for this argument is that I believe the real problem here stems from "InstancePerLifetimeScope", so I'm wondering if this warrants the possibility of another solution.
The examples given by Autofac and the link to Mark Seemann blog post (Which is a good resource to understand captive dependency, just with a bad example), try to show a captive dependency for a singleton occurring which has an dependency that's registered as "Instance Per Dependency". The problem is that this example (shown below) is wrong in pointing out the actual problem. "ProductService" is registered as a singleton, so after it's resolved the first time it'll always return the same "ProductService" reference which the example implies is not the case.
Incorrect Example Linked by AutoFac Doc
// Example from https://blog.ploeh.dk/2014/06/02/captive-dependency/
var builder = new ContainerBuilder();
builder.RegisterType<ProductService>().SingleInstance();
builder.RegisterType<SqlProductRepository>().As<IProductRepository>();
builder.RegisterType<CommerceContext>();
var container = builder.Build();
var actual1 = container.Resolve<ProductService>();
var actual2 = container.Resolve<ProductService>();
// You'd want this assertion to pass, but it fails
Assert.NotEqual(actual1.Repository, actual2.Repository);
// Lightbarrier snippet: Ya but guess what this also fails
Assert.NotEqual(actual1, actual2);
From the above code it's implied that captive dependency can occur for an "Instance Per Dependency" registration however, as shown by the below example that's not the case.
Example of what's actually happening
var builder = new ContainerBuilder();
// Register
builder.RegisterType<Logger>().As<ILogger>(); // InstancePerDependency
builder.RegisterType<Test.Service.Service1>().As<IService1>().SingleInstance();
builder.RegisterType<Test.Service.Service2>().As<IService2>().SingleInstance();
// Build
var container = builder.Build();
// Resolve
IService1 firstService = container.Resolve<IService1>();
IService2 secondService = container.Resolve<IService2>();
// This is false in that "InstancePerDependency" didn't result in a Captive Dependency
if (((Test.Service.Service1)firstService)._logger == ((Test.Service.Service2)secondService)._logger)
{
throw new Exception("Loggers were the same");
}
What this means is that a captive dependency can only occur when you try register a class's lifetime to reside in the current scope it was resolved in or greater/parented scope.
What others have suggested is that just having your Singleton's dependencies be registered instance by dependency shouldn't make a big difference however, I think this is missing the whole point. There are cases where reusing the same dependency is important, I use the logger as a prime example where having multiple resolutions can lead to fighting over external resources like where data is being logged. What more, most of these captive dependency issues can be avoided simply by avoiding registering Singletons, as if your sharing within the child scopes you can at least close the child, but with singletons the dependency is captured in the root. And yet I would argue that these dependencies can be resolved as we desired without capture dependencies if we were to not use a IOC library like Autofac and pass them in manually ourselves, so logically it should be possible for AutoFac to do it if we can. However, I want Autofac to do the work for me and yet this is a huge trap to run into that I think most people should be aware of when they're looking at IOC libraries.
Question:
I've read that updating Autofac to resolve this issue for shared registered components would be difficult be difficult to program, but is it really that hard for Autofac to know the singleton's dependencies that are registered to be shared across the scope should reside on said current scope only, and not the root scope where the Singleton will reside? I would venture that when a Singleton instance is resolved, the instance's dependencies do not need to reside in the root scope in order for the singleton instance to exist, as they will exist in memory due to their reference in the singleton instance, thus there's no reason for the root scope to save these dependencies.
If this is really the case, the only path seems to be to never use the Singleton functionality within AutoFac and to find another way to work around it. That said I think there should be a huge warning about this problem in the Singleton portion of AutoFac's documentation which is currently missing.

Multiple viewmodel using Caliburn Micro and MEF

I am designing a WPF application with several ViewModels, and I am using Caliburn Micro and MEF. Unfortunately, I am absolutely new to MEF and IoC, and can't solve a problem.
The application is supposed to have a MainView, where several options are enlisted, like: Create a new record, Edit older records, View reports, etc. So, for each of those units, I have different classes for ViewModels like CreateRecordViewModel, EditRecordsViewModel, ViewReportsViewModel, and Usercontrols for Views like CreateRecordView, EditRecordsView, ViewReportsView etc.
Now, the MainViewModel is a Conductor, and I am using code like this:
public class ShellViewModel : Conductor<object>
{
public void ShowCreateRecord()
{
ActivateItem(new CreateRecordViewModel(...Dependencies...));
}
public void ShowEditRecords()
{
ActivateItem(new EditRecordsViewModel(...Dependencies...));
}
...
}
Since the MEF container resides in Bootstrapper, I am a bit lost about how to use Constructor Injection in this MainViewModel. And my second concern is about GC. How can I test if the created ViewModels are properly disposed of?
I know these questions might seem a bit asinine, but I would really appreciate a solution. Should I decorate my Property setters with [Import] instead of going for Constructor Injection?
I am not familiar with MEF myself, but most of the DIs work in a similar idea.
You have to inject the container's (MEF container) into the view models, and resolve the appropriate viewmodels using the container.
You're not supposed to instantiate viewmodels by yourself, instead, in the main vm, inject the container resolving service, via constructor or property injection (again - not so familiar with MEF), then call ActivateItem(_DependencyService.Resolve<CreateRecordViewModel>());.
And BTW, the Main VM itself should also be instantiated by the container, so you obviously don't need to manually inject the container to the main vm.
IoC is just about trusting the container to resolve anything for you, otherwise, its the container registered types that are misregistered:
public class ShellViewModel : Conductor<object>
{
private readonly IMefDependencyContainer _container;
public ShellViewModel(IMefDependencyContainer container) {
_container = container;
}
public void ShowCreateRecord()
{
ActivateItem(_container.Resolve<CreateRecordViewModel>());
}
}
Replace IMefDependencyContainer and Resolve with its names in MEF.

Correctly use Dependency Injection pattern [duplicate]

I'm currently working on a WinForms system (I know) where there's a lot of Constructor Injection when creating forms, but if those forms/views need to open another form, I find the DI container has been injected too so that we can locate the implementation of the desired view interface at runtime. e.g.
public partial class MyView : Form, IMyView
{
private readonly IDIContainer _container;
public MyView(IDIContainer container)
{
InitializeComponent();
_container = container;
}
public OpenDialogClick(object sender, EventArgs e)
{
var dialog = container.Resolve<IDialogView>();
dialog.ShowDialog(this);
}
}
I'm aware that this is basically using the container as a service locator. I've been repeatedly told that this is considered an anti-pattern so I'd like to avoid this usage.
I could probably inject the view as part of the constructor like this :
public partial class MyView : Form, IMyView
{
private readonly IDialogView _dialog;
public MyView(IDialogView dialog)
{
InitializeComponent();
_dialog = dialog;
}
public OpenDialogClick(object sender, EventArgs e)
{
dialog.ShowDialog(this);
}
}
But what if the dialog view is quite expensive to instantiate?
It's been suggested that we create some kind of form factory which internally uses the DI container, but to me this seems like simply creating a wrapper around another service locator.
I know that at some point, something has to know how to create an IDialogView, so I'm thinking that either it's resolved when the composite root is created (probably not ideal if there are many forms and some or all are expensive to create), or the composite root itself has a way to resolve the dependency. In which case the composite root has to have a service-locator-like dependency? But then how would child forms create dialogs like this? Would they call up to the composite via, say, events, to open dialogs like this?
One particular problem I keep running up against is that the container is almost impossible to mock easily. This is partly what keeps me thinking about the form factory idea, even though it would just be a wrapper around the container. Is that a sensible reason?
Have I thought myself into a knot? Is there a simple way through this? Or do I just cut the knot and find something that works for me?
Or do I just cut the knot and find something that works for me?
Factory class:
public interface IDialogFactory {
IDialogView CreateNew();
}
// Implementation
sealed class DialogFactory: IDialogFactory {
public IDialogView CreateNew() {
return new DialogImpl();
}
}
// or singleton...
sealed class SingleDialogFactory: IDialogFactory {
private IDialogView dialog;
public IDialogView CreateNew() {
if (dialog == null) {
dialog = new DialogImpl();
}
return dialog;
}
}
Your code:
public partial class MyView : Form, IMyView {
private readonly IDialogFactory factory;
public MyView(IDialogFactory factory) {
InitializeComponent();
//assert(factory != null);
this.factory = factory;
}
public OpenDialogClick(object sender, EventArgs e) {
using (var dialog = this.factory.CreateNew()) {
dialog.ShowDialog(this);
}
}
}
Registration with SimpleInjector
container.RegisterSingle<IDialogFactory, DialogFactory>();
or using singleton version
container.RegisterSingle<IDialogFactory, SingleDialogFactory>();
container.RegisterSingle<IMyView, MyView>();
A local factory, satisfied with an implementation that uses the container and set up in the composition root is not a service locator, it is a dependency resolver.
The difference is as follows: the locator is defined and satisfied somewhere near the definition of the container. In a separate project, to use the locator, you need an external reference to the container infrastructure. This causes the project to rely on external dependency (the locator).
On the other hand, the dependency resolver is local to the project. It is used to satisfy dependencies in its close neighbourhood but it doesn't depend on anything external.
The composition root should not be used to resolve actual specific dependencies such as the one you are concerned about. Instead, the compositon root should set up implementations of all these local dependency resolvers that are used throughout the application. The more local resolver, the better - the MVC's constructor factory is a good example. On the other hand, WebAPI's resolver handles quite few of different services and it is still a good resolver - it is local in the webapi infrastructure, it doesn't depend on anything (rather - other webapi services depend on it) and it can be implemented in any possible way and set up in the Composition Root.
Some time ago I wrote a blog entry about it
http://www.wiktorzychla.com/2012/12/di-factories-and-composition-root.html
There you will find your issue discussed and an example of how you set up a factory aka resolver.
You definitely do not want to pass your DI container around your application. Your DI container should only be part of your Composition Root. You could, however, have a factory that uses the DI container within the Composition Root. So if Program.cs is where you are wiring everything up, you could simply define that factory class there.
WinForms was not designed with DI in mind; forms are generated and therefore need default constructors. This may or may not be an issue depending on which DI container you use.
I think in this case, the pain of using constructor injection in WinForms is greater than the pain of any pitfalls you may encounter while using a service locator. There's no shame in declaring a static method in your Composition Root (Program.cs) that wraps a call to your DI container to resolve your references.
I know this problem very well. Everything I learned about solution to this (and I learned A LOT) is more or less camouflaging service locator.

Get the container instance for Simple Injector

I am using Simple Injector with a ASP.NET MVC project. I added the SimpleInjector.Integration.Web.Mvc nuget package. This adds SimpleInjectorInitializer class in App_Start folder and initializes the DI. The code looks something like
public static void Initialize()
{
// Did you know the container can diagnose your configuration?
// Go to: https://simpleinjector.org/diagnostics
var container = new Container();
//Container configuration code
DependencyResolver.SetResolver(
new SimpleInjectorDependencyResolver(container));
}
This configures the DI for the MVC controller correctly.
My question is, if I want to get the instance of the container in any of the controller\class to resolve some dependency manually how can I do it.
I have earlier worked on AutoFac and it has a dependency interface IComponentContext which can be injected into any class that needs to do any resolution manually.
Update:
Here is a scenario. My controller uses a service who initialization depends upon the input parameter passed in the controller method and hence the dependency cannot be instantiated during construction time.
I understand that this is somewhat an anti pattern for DI, but it is requirement at few places and hence injecting the DI container is next best thing. Simple Injector samples should use of static variable to share the container which i want to avoid and also it is not possible by the way SimpleInjectorInitializer works.
Except for any code that is part of the startup path of the application, no code should depend directly on the container (or a container abstraction, container facade, etc). This pattern is called Service Locator and Mark Seemann has a good explanation why this is a bad idea.
So components (such as Controllers) should not depend on the container directly, since this hides the used dependencies and makes classes harder to test. Furthermore your code starts to depend on an external framework (making it harder to change) or depending on an abstraction it doesn't need to know about.
My controller uses a service who initialization depends upon the input
parameter passed in the controller method and hence the dependency
cannot be instantiated during construction time
There's a general pattern for this problem: the abstract factory design pattern. The factory pattern allows you to delay the creation of types and allows you to pass in extra runtime parameters for the construction of a certain type. When you do this, your controller doesn't have to depend on Container and it prevents you from having to pass in a constructed container in your unit tests (DI frameworks should in general not be used in your unit test projects).
Do note however that letting your components require runtime data during creation is a code smell. Prevent doing that.
You might think that by doing this we are just moving the problem to the factory implementation. Although we are moving the dependency on the container into the factory implementation, we are in fact solving the problem because the factory implementation will be part of the application's Composition Root, which allows the application code itself oblivious to any DI framework.
So this is how I advice you to structure your code:
// Definition of the factory in the UI or BL layer
public interface ISomeServiceFactory
{
ISomeService Create(int inputParameter);
}
// Controller depending on that factory:
public class MyController : Controller
{
private readonly ISomeServiceFactory factory;
public MyController(ISomeServiceFactory factory)
{
this.factory = factory;
}
public ActionResult Index(int value)
{
// here we use that factory
var service = this.factory.Create(value);
}
}
In your composition root (the start up path) we define the factory implementation and the registration for it:
private class SomeServiceFactory : ISomeServiceFactory
{
private readonly Container container;
// Here we depend on Container, which is fine, since
// we're inside the composition root. The rest of the
// application knows nothing about a DI framework.
public SomeServiceFactory(Container container)
{
this.container = container;
}
public ISomeService Create(int inputParameter)
{
// Do what ever we need to do here. For instance:
if (inputParameter == 0)
return this.container.GetInstance<Service1>();
else
return this.container.GetInstance<Service2>();
}
}
public static void Initialize()
{
var container = new Container();
container.RegisterSingle<ISomeServiceFactory, SomeServiceFactory>();
}
Upon creation, the Container registers itself (using the call RegisterSingle<Container>(this)) so you can always inject the container into any component. That's similar to injecting the IComponentContext when working with Autofac. But the same holds for Autofac, Simple Injector, and any other container: you don't want to inject your container into components that are located outside the composition root (and there hardly ever is a reason for it).

Should creating a Unity Container be considered an expensive operation as it relates to resources and time?

I've recently started using Unity for dependency injections in .net.
I was under the impression that a Unity Container would most likely be a singleton or static member of a class. I saw another developer using it in a request handler that will receive a lot of traffic.
Is there some magic happening that keeps the cost low for creating a new Unity Container every time, or should this code be re-factored to only create the Unity container once?
This code is part of the implementing class of a .svc Service.
public string DoSomeWork(Request request)
{
var container = new UnityContainer().LoadConfiguration("MyContainer");
var handler = container.Resolve<RequestHandler>();
return handler.Handle(request);
}
Not 100% sure with Unity, but with most IoC containers, the creation of the container and especially the loading of container configuration is a reasonably expensive operation.
I have to question why this developer is utilizing the container in this manner however. Ideally the IoC container shouldn't even be a static or singleton object - it should be instantiated only to resolve the top level object of your dependency tree, and the rest of the objects in your application should be constructed automatically through dependency injection. In the case of your example, the class containing that method ideally would have the RequestHandler (ideally an interface of this) injected into it through the constructor so that class does not need to know about the IoC container.
This is not the right way to use an IOC container - basically your are using it as a service locator, but this will cause dependencies to the IOC container to be sprinkled all over the code base.
What you should do is have one central spot in your codebase where all dependencies are resolved and then use dependency injection (DI) to propagate the resolved concrete classes down the chain, i.e via constructor injection. So your class really should look something like this:
public class Foo
{
private readonly IRequestHandler _handler;
public Foo(IRequestHandler handler)
{
_handler = handler;
}
public string DoSomeWork(Request request)
{
return _handler.Handle(request);
}
}

Categories

Resources