IOC/DI container and child window creation dilemma - c#

I am trying to using IOC/DI container, but when come to creating a child window, what's the best practice?
Where I am having dilemma is :
public class ParentWindow : Form
{
public void OpenChildWindow()
{
var child = IocContainer.Instance.Resolve<ChildWindow>(); // big issue !!! an-ti server locator pattern
child.Show();
}
}
Or
public class ParentWindow : Form
{
private Container _container
public ParentWindow(Container container) // no, no, you have dependence on container
{
}
public void OpenChildWindow()
{
var child = _container.Resolve<ChildWindow>();
child.Show();
}
}
My solution
public class ParentWindow : Form
{
private IFormFactory _factory
public ParentWindow(IFormFactory factory) // inject from IOC container
{
}
public void OpenChildWindow()
{
var child = _factory.CreateChildWindow();
child.Show();
}
}
But with my solution, my factory kind of become my own IOC container, all my parent-ish window have to pass in a factory , isn't this make my factory become the new "server locator".
Is there any other better solution for this ?

The solution you suggest is a huge step in a right direction. The factory doesn't really smell like a locator, rather, it is a local factory, part of the domain it belongs to.
A step even further would be to forget the idea of family of factories (the interface) and have a concrete factory with pluggable implementation that internally uses a container (or doesn't use one) but offers a single api for its clients. This way you could remove the constructor injection of the factory into the form in favor of just using the factory's concrete type. The factory itself is configured in the Composition Root.
More details and code example in my blog entry
http://www.wiktorzychla.com/2016/01/di-factories-and-composition-root.html

First example: I don't like because you also has dependency which you cannot Unit test. It will resolve instance of ChildWindow and you cannot control (mock) it.
Second example: I don't like because you are using class Container not interface.
Third example: It will works better than previous and sometimes I use factory on that way. It it can be fully unit tested.
Usually I think that is better to use DI container as factory because it provides more functionalities such as e.g. object lifetime...
I never used class ChildWindow but if I cannot define in constructor interface i will rather implement some ChildWindowWrapper : IChildWindowWrapper and use that wrapper. It will simplefy unit testing and it can be used from DI container.

Using DI implies that you consume the container as a Service Locator somewhere, preferably in one single line of code which executes exactly once. This is referred to as the "Composition Root", where the container is configured and the root of the object graph is created.
With this in mind- the topmost code in your example does not violate this principle.
SIDENOTE:
What I always do is wrap the Container framework code with my own class so that I can switch DI frameworks more easily- consider it.

Related

theory: "Service Locator" "IOC Container" "IOC" "DI"

can you help me with theory of some patterns. I have tried to describe them, I have tried my best, but I think my statements are wrong, so help )).
1) "DI" and "IOC" - the same.
2) "IOC Container" - it is an instance of an object that can resolve dependences like:
void Test()
{
// create IOC Container to resolve
// dependences for SomeMethod method
var container = new SomeContainer();
container.For(typeof(IEmaleSender), typeof(SuperEmaleSender));
// Pass IOC Container to resolve dependences in SomeMethod
SomeMethod(container);
}
void SomeMethod(SomeContainer container)
{
IEmaleSender emailSender = container.Resolve(IEmaleSender);
emailSender.SendEmail();
}
3) "Service Locator" - It is something like static object that contains Dictionary<Type, object> where value is an instance of key type. And this static object have 2 methods: Add and Get. So I can add object on start of my application and request it from everywhere:
void Test()
{
// Assign instanse of SuperEmaleSender to Locator
SuperEmaleSender emailSender = new SuperEmaleSender()
SomeLocator.Add(typeof(SuperEmaleSender), emailSender);
SomeMethod();
}
void SomeMethod()
{
SuperEmaleSender emailSender = SomeLocator.Get(typeof(SuperEmaleSender));
emailSender.SendEmail();
}
4) It is a good practice to combine "Service Locator" and "IOC Container". So you can instantiate "IOC Container" on application start and request it through "Service Locator" from everywhere.
5) In ASP MVC5, "Service Locator" already included. I'm talking about DependencyResolver.
Thank you for your help.
As for the combining service locator with IoC - when you have proper IoC container, you really shouldn't use service locator (or perhaps in most cases you should not use it at all), because the whole point of IoC and DI is to pass dependencies from outside of class and specify explicitely what dependecies this class has. Using service locator inside would hide the dependency. Service locator is by some people considered an anti-pattern.
Service Locator is ALMOST an extremely primitive Dependency Injection. It generally only lets you return singleton instances. Its not really DI because you have to get instances by hand and new up objects by hand rather then let the DI engine do it for you (new up object and inject the service references into them). DI also gives you more control over the lifetime of the objects.
DI stands for Depency Injection and IoC for Inversion of Control.
Imagine you have a class that access the database. The responsability of that class is to insert an item, but you need a database connection to do so. If the responsability of the class is only to insert an item, it won't know how to start that connection, only how to use it. Thinking of it, you'll set the connection as a dependency of that class, passing the responsability of creating that connection to anyone that want to use it. You are inverting the control using dependency injection, passing the responsability to anyone that knows how a connection works.
You can use an IoC container to help you manage the dependencies between your classes.
You can see this question for a more detailed answer: Inversion of Control vs Dependency Injection

Ninject Auto Instantiate singleton instance [duplicate]

I have some services in my asp.net mvc application that listen for AMQP messages and invoke methods.
No controllers depend on this, so it won't get instantiated on its own.
I could instantiate it manually, explicitly providing its dependencies with kernel.Get but it feels like I shouldn't have to do that.
Can I make Ninject instantiate classes in singleton scope eagerly even when nothing else depends on it?
You cannot have ninject instantiate stuff in case you don't ask it to instantiate something yourself.
The simple way is to ask ninject to instantiate things at composition root:
var kernel = new StandardKernel();
kernel.Bind<IFoo>().To<Foo>();
kernel.Load(AppDomain.CurrentDomain.GetAssemblies()); // loads all modules in assemlby
//...
// resolution root completely configured
kernel.Resolve<IFooSingleton>();
kernel.Resolve<IBarSIngleton>();
There is one alternative, actually, which is not the same, but can be used to achieve a similar effect. It requires that there is at least one single other service instantiated soon enough: Ninject.Extensions.DependencyCreation.
It works like this:
kernel.Bind<string>().ToConstant("hello");
kernel.Bind<ISingletonDependency>().To<SingletonDependency>()
.InSingletonScope();
kernel.DefineDependency<string, ISingletonDependency>();
kernel.Get<string>();
// when asking for a string for the first time
// ISingletonDependency will be instantiated.
// of course you can use any other type instead of string
Why
Ninject is unlike some other containers (for example Autofac) not "built" in stages. There's no concept of first creating the bindings, and then creating the kernel to use them. The following is perfectly legal:
kernel.Bind<IFoo>()...
kernel.Get<IFoo>()...
kernel.Bind<IBar>()...
kernel.Get<IBar>()...
so ninject can't possibly know when you want the singletons to be instantiated. With autofac it's clear and easy:
var containerBuilder = new ContainerBuilder();
containerBuilder
.RegisterType<Foo>()
.AutoActivate();
var container = containerBuilder.Build(); // now
Coming from Guice in Java, I've sorely missed the pattern of eager singletons. They are useful in scenarios where for example modules act as plugins. If you imagine that a service is assembled from modules that are specified in a configuration, you could see a problem of then also trying to specify what this module needs to be auto-instantiated when the application is started.
For me the module is where the composition of the application is defined and separating eager singletons into another place in the code feels more clunky and less intuitive.
Anyway, I've been able to very easily implement this as a layer on top of Ninject, here's the code:
public static class EagerSingleton
{
public static IBindingNamedWithOrOnSyntax<T> AsEagerSingleton<T>(this IBindingInSyntax<T> binding)
{
var r = binding.InSingletonScope();
binding.Kernel.Bind<IEagerSingleton>().To<EagerSingleton<T>>().InSingletonScope();
return r;
}
}
public interface IEagerSingleton { }
public class EagerSingleton<TComponent> : IEagerSingleton
{
public EagerSingleton(TComponent component)
{
// do nothing. DI created the component for this constructor.
}
}
public class EagerSingletonSvc
{
public EagerSingletonSvc(IEagerSingleton[] singletons)
{
// do nothing. DI created all the singletons for this constructor.
}
}
After you've created your kernel, add a single line:
kernel.Get<EagerSingletonSvc>(); // activate all eager singletons
You use it in a module like this:
Bind<UnhandledExceptionHandlerSvc>().ToSelf().AsEagerSingleton();

Avoiding a nested service locator antipattern with DI / autofac

I had something of a convenient service locator anti-pattern in a previous game project. I'd like to replace this with dependency injection. autofac looks like the most likely DI container for me as it seems to have relevant features - but I can't figure out how to achieve what I'm looking for.
Existing Approach
Rather than a single service locator, I had a service locator which could delegate to its parent (in effect providing "scoped" services):
class ServiceLocator {
ServiceLocator _parent;
Dictionary<Type, object> _registered = new Dictionary<Type, object>();
public ServiceLocator(ServiceLocator parent = null) {
_parent = parent;
}
public void Register<T>(T service) {
_registered.Add(typeof(T), service);
}
public T Get<T>() {
object service;
if (_registered.TryGetValue(typeof(T), out service)) {
return (T)service;
}
return _parent.Get<T>();
}
}
Simplifying for clarity, the game consisted of a tree of Component-derived classes:
abstract class Component {
protected ServiceLocator _ownServices;
protected List<Component> _components = new List<Component>();
...
public Component(ServiceLocator parentServices) {
_ownServices = new ServiceLocator(parentServices);
}
...
}
So I could (and did) build tree structures like:
Game
- Audio : IAudioService
- TitleScreen : Screen
- GameplayScreen : Screen
- ShootingComponent : IShootingService
- NavigationComponent : INavigationService
|- AIComponent (uses IAudioService and IShootingService and INavigationService)
And each component could simply call the ServiceLocator with which it's constructed to find all the services it needs.
Benefits:
Components don't have to care who implements the services they use or where those services live; so long as those services' lifetimes are equal to or greater than their own.
Multiple components can share the same service, but that service can exist only as long as it needs to. In particular, we can Dispose() a whole portion of the hierarchy when the player quits a level, which is far easier than having components rebuild complex data structures to adjust to the idea that they're now in a completely new level.
Drawbacks:
As Mark Seeman points out, Service Locator is an Anti-Pattern.
Some components would instantiate service providers purely because I (the programmer) know that nested components need that service, or I (the programmer) know that the game has to have e.g. AI running in the game world, not because the instantiator requires that service per se.
Goal
In the spirit of DI, I would like to remove all knowledge of "service locators" and "scopes" from Components. So they would receive (via DI) constructor parameters for each service they consume. To keep this knowledge out of the components, the composition root will have to specify, for each component:
Whether instantiating a specific type of component creates a new scope
Within that scope, which services are available.
I want to write the intuitive:
class AIComponent
{
public AIComponent(IAudioService audio, IShootingService shooting, INavigationService navigation)
{
...
}
}
And be able to specify in the composition root that
IAudioService is implemented by the Audio class and you should create/obtain a singleton (I can do this!)
IShootingService is implemented by ShootingComponent and there should be one of those created/obtained per Screen
INavigationService as per IShootingService
I must confess I'm completely lost when it comes to the latter two. I won't list my numerous abortive autofac-based attempts here as I've made a few dozen over a long period and none of them were remotely functional. I have read the documentation at length - I know lifetime scopes and Owned<> are in the area I'm looking at, but I can't see how to transparently inject scoped dependencies as I'm looking to - yet I feel that DI in general seems supposed to facilitate exactly what I'm looking to do!
If this is sane, how can I achieve this? Or is this just diabolical? If so, how would you structure such an application making good use of DI to avoid passing objects around recursively, when the lifetimes of those objects vary depending on the context in which the object is being used?
LifetimeScopes sound like the answer. I think what you are basically doing is tying lifetime scopes to screens. So ShootingComponent and friends would be registered with .InstancePerMatchingLifetimeScope("Screen"). The trick is then making it so that each screen is created in a new LifetimeScope tagged as "Screen." My first thought would be to make a screen factory like so:
public class ScreenFactory
{
private readonly ILifetimeScope _parent;
public ScreenFactory(ILifetimeScope parent) { _parent = parent; }
public TScreen CreateScreen<TScreen>() where TScreen : Screen
{
var screenScope = _parent.BeginLifetimeScope("Screen");
var screen = screenScope.Resolve<TScreen>();
screen.Closed += () => screenScope.Dispose();
return screen;
}
}
This is totally untested, but I think the concept makes sense.
Coincidentally currently I am working with similar requirements (Using Autofac) and here is what I came up with so far:
First of all start using modules. They are an excellent way of managing your dependencies and configuration.
Define your dependencies with appropriate lifetimes: IAudioService as singleton and IShootingService as per lifetime scope.
Make sure your lifetime scoped interfaces also implements IDisposable to ensure proper clean up.
Create a thin wrapper to manage all your lifetime in a simple embedded framework: sandwich your game levels between Begin() and End() methods. (this is how I did it. I'm sure you can find a better way of doing this in your own structure)
(optional) Create a 'core' module to keep your generic dependencies (i.e. IAudioService) and separate modules for other islands of dependencies (which might be depending on different implementations of the same interface for example)
Here is an example of how I did it:
public ScopedObjects(ILifetimeScope container, IModule module)
{
_c = container;
_m = module;
}
public void Begin()
{
_scope = _c.BeginLifetimeScope(b => b.RegisterModule(_m));
}
public T Resolve<T>()
{
return _scope.Resolve<T>();
}
public void End()
{
_scope.Dispose();
}
In the example you gave, I would put the resolution of AIComponent between Begin and End calls of the above class when going through levels.
As I said, I'm sure you will be able to come up with a better way of doing it in your development structure, I hope this gives you the basic idea as to how you can implement it, assuming my experience is to be considered a 'good' way of doing this.
Good luck.

Confusion about DI, IoC and service locators

I have read various articles about IoC, DIP, DI and Service Locators but I'm a bit confused which is which because some articles have too vague examples and some other articles have just some specific examples without mentioning other cases.
Could you please clear this up for me, looking at the examples below and shortly explaining which examples match which pattern?
manually passing interface to constructor:
class Consumer
{
public Consumer(IStore store){...}
}
...
Consumer c = new Consumer(new ConcreteStore());
the same as the first example but using some 3rd party library (Unity, Windsor, Ninject)
the same as the first example but using BaseStore class instead of IStore interface
passing dependency to some other method, not to constructor:
class Consumer
{
public BySomething(IStore store){...}
}
...
Consumer c = new Consumer();
c.BySomething(new ConcreteStore());
passing dependencies masked inside of some other interface (bonus for this solution - when some other things are invented in the "world" and Consumer wishes to use them, we don't have to change constructor argument but just update IWorld; and we can completely replace entire World with something else when testing):
interface IWorld
{
IDictionary<string,IStore> Stores { get; set; }
IDictionary<string,ICityMap> Maps { get; set; }
...
}
class Consumer
{
public Consumer(IWorld world){...}
public BySomething(string store, string city){...}
}
...
IWorld myWorld = new HeavenlyWorld();
... // adding stores, maps and whatnot
Consumer c = new Consumer(myWorld);
a sub-question: in this case, is IWorld a service locator or not exactly?
passing a call-back function or delegate (.NET Action in this case):
c.BySomething(store, city, new Action(() => {...} ));
I added this case because the article Inversion of Control states that every callback is IoC. Is it true?
Everything you listed is a form of Dependency Injection.
"Poor Man's" DI
DI using an IoC container
"Poor Man's" DI again. DI works whether you are using an interface or an abstract class.
Method Injection
I'm not sure what you're asking here. It sounds like you want to change the instance of IWorld at runtime, which might be a case for Property Injection instead of Constructor Injection. Properties are oft used for optional dependencies or those that can change. Whether you then set that dependency at run-time with a Service Locator or other means is up to you. Another thing to consider is that IWorld might just depend on context, in which case you could do a context-depdendent constructor injection, the details of which are beyond the scope of this question.
Not related to DI
Every time you pass a dependency as a constructor/method argument, that's Dependecy Injection. It can be manual, like in most of your examples, or automatic using a DI Container aka IoC Container.
Using a container means the objects using deps are constructed by the container. You could ask the container directly for that service and in that case, there's a static property or method ( think DependecyResolver in asp.net mvc) that exposes that service. In that case you're using the Service Locator pattern. IWork in your example is not a locator, it's just a dependency.
To continue with the dependency resolver example, you register all relevant types into a container, the container is build then registered as the dependency resolver. The asp.net mvc framwork then uses the resolver (the Service Locator - SL) to instantiate controllers, views and all the deps these require.
To use the SL pattern is ok as part of a framework, but it's not ok if you're using it in your app to instantiate objects, because it couples the code to the locator. Sometimes is the only solution but 99% you is just an anti-pattern.

Replacing ServiceLocator with DependencyInjection when implementing modal dialogs in MVVM WPF application

I am writing my first WPF application and I would like to ask you for help with a problem that I encountered.
I am trying to follow the MVVM pattern and I came to a point where I need to implement modal dialogs. I googled/read on the topic for some time and I was able to settle on a solution. However, when refactoring I encountered a dilemma that concerns using a DI (constructor injection) as a replacement of a service locator.
I am going to be referencing these: http://pastebin.com/S6xNjtWW.
I really like the approach of Roboblob:
First: He creates an abstraction of a modal dialog (interface). I named the interface IModalDialog and this is how it looks like:
public interface IModalDialog
{
bool? DialogResult { get; set; }
object DataContext { get; set; }
void Show();
bool? ShowDialog();
void Close();
event EventHandler Closed;
}
Second: An abstraction of modal dialog service:
public interface IModalDialogService
{
void ShowDialog<TDialogViewModel>(IModalDialog view, TDialogViewModel viewModel, Action<TDialogViewModel> onDialogClose) where TDialogViewModel : class;
void ShowDialog<TDialogViewModel>(IModalDialog view, TDialogViewModel viewModel) where TDialogViewModel : class;
}
Third: The concrete implementation of IModalDialogService:
public class ModalDialogService : IModalDialogService
{
public void ShowDialog<TDialogViewModel>(IModalDialog view, TDialogViewModel viewModel, Action<TDialogViewModel> onDialogClose) where TDialogViewModel : class
{
// set datacontext
if (viewModel != null)
{
view.DataContext = viewModel;
}
((System.Windows.Window)view).Owner = System.Windows.Application.Current.MainWindow;
// register
if (onDialogClose != null)
{
view.Closed += (sender, e) => onDialogClose(viewModel);
}
view.ShowDialog();
}
public void ShowDialog<TDialogViewModel>(IModalDialog view, TDialogViewModel viewModel) where TDialogViewModel : class
{
this.ShowDialog(view, viewModel, null);
}
Fourth: There are more implementations of IModalDialog. Each is a Window-derived class that implements IModalDialog.
Before I ask the question (describe the problem), I need to explain this beforehand:
Let's say that I have some more services, like for example IMessageBoxService.
Then I need to declare these dependencies in the constructor of MainWindowViewModel:
public MainWindowViewModel(IModalDialogService a,
IMessageBoxService b,
...)
so that I can inject them (either by hand or using IOC container like Unity, etc.).
In order to be able to use the modal dialog service there is one missing piece of puzzle - the ability to resolve a concrete implementation of IModalDialog based on some key.
Roboblob in his article solves this last piece of puzzle using a ServiceLocator pattern:
public class Bootstrapper
{
public static void InitializeIoc()
{
SimpleServiceLocator.SetServiceLocatorProvider(new UnityServiceLocator());
SimpleServiceLocator.Instance.Register<IModalDialogService, ModalDialogService>();
SimpleServiceLocator.Instance.Register<IMessageBoxService, MessageBoxService>();
...
SimpleServiceLocator.Instance.Register<IModalWindow, EditUserModalDialogView>(Constants.EditUserModalDialog);
}
}
so he inside his MainWindowViewModel simply calls the static classes Get and resolves a concrete implementation of IModalDialog window based on a key.
Even Josh Smith uses a similar approach in his article but in comments he says that (DI - constructor injection) is a valid option.
The referenced StackOverflow answer also describes a similar WindowViewLoaderService that could be modified and use.
So the question is - what would be the best way to replace the ServiceLocator (which resolves the concrete implementations of IModalDialog) with a dependency injection?
My train of thoughts was:
One possibility is (due to the project not being very big/developed by me only) to just create a new service (e.g. called IModalDialogResolver) that would create and return new instances of concrete implementations of IModalDialog. Have all the services injected by hand.
Then I thought about an IOC container (Unity). I have no experience with it. I thought that maybe I don't have to write the IModalDialogResolver as I could register the different implementations of IModalDialog with Unity container => but then how do I use the container inside MainWindowViewModel? I cannot pass the reference to the constructor as that would be a step back to ServiceLocation.
So then I thought that maybe I can use one unity container in the bootstrapper to resolve all the services and use another one internally inside the IModalDialogResolver. But I don't know whether this is a good idea regarding the recommended usage of Unity. I really know too little to judge this. But something tells me that this is not a good idea as it creates a hidden dependency on the container + if the container is a singleton that would be equivalent to just passing the reference into the constructor.
To maybe better explain the mental block that I have: I would like to use an IOC container (e.g. Unity) to have the interfaces constructed and injected by it. But then I cannot just put IModalDialog as a parameter inside a constructor. So probably I really need to wrap this inside a service and implement myself - but then (provided that Unity can do this out of the box) it doesn't make sense to have Unity there in the first place if i cannot use it.
I know one of the alternatives is to put this one service into a base class, but for the sake of argument, let's not consider this. I really would like to learn about the right way to have this solved using dependency injection.
It's perfectly valid and expected for you to access the IoC container within your composition root.
In fact this should be the only location where you container is accessed.
In the example you've given, that's all that is happening - the concrete implementations are being registered in the container within the composition root.
So to answer your question, you don't need to replace the use of the service locator pattern here, as it's just a mechanism for registering the types in the composition root, which is perfectly valid.
If you wish to instantiate the modal dialog service based on some run time conditions, then you should inject a model dialog service factory instead (again an abstraction with an implementation registered in your container), and then the factory would have a method to create the model dialog service and this factory method would take the run time parameters required.
Your factory could then new up the appropriate model dialog service appropriately based on the run time parameters. Alternatively, it could also resolve the appropriate model dialog service from the container, which would obviously require the factory to have a reference to the container.
Most containers support automated factory types, so that you only need to define the interface for the factory, and the container will automatically implement the factory using conventions. Castle.Windsor for example has the Typed Factory Facility and Unity has some equivalents.

Categories

Resources