I'm using Windsor to do IoC in our .Net project, but I'm having difficulties doing setter injection in code.
I believe it comes from the fact that I blanket register my components, since eventually I'm hoping that legacy project will be fully IoC compliant and mostly Unit Tested (sweet dreams!).
Here is how I'm registering the DAOs:
container
.Register(AllTypes.FromAssemblyNamed("MyApp.Business")
.Where(Component.IsInNamespace("MyApp.Business.Dao"))
.WithService.DefaultInterface());
And here is how I'm registering the components using the DAOs:
container
.Register(AllTypes.FromAssemblyNamed("MyApp.Business")
.Where(Component.IsInNamespace("MyApp.MyComponentObject")));
I was hoping that the setters would get picked up automatically in the components, but the resources I found seem to show the setters need to be defined.
Unfortunately I've only found examples of how to do that in the configuration XML, not in the code.
I found how to add a parameter to a component in the code but there seem to be limitations. Looks like it has to be a string and even if that's not the case, seems like it would force me to declare those components one by one instead of just blanket registering. That code would become huge if I had to do that and somehow Windsor would lose some of its appeal to me.
I remember using Spring were if a bean was declared autowiring would inject it without any issue.
Am I missing something w/ Windsor here?
===============
More information:
In the component class that will use the Dao component here is how I declare the setter:
private IMyDao dao = null;
public IMyDao Dao
{
set { this.dao = value; }
}
The main reason I want to setter inject is because I can't change the constructors without having a pretty impact on the legacy app.
===============
Update:
Have commented out most of my registration code, left just this to see if that works in a simple case scenario and it did not:
//DAOs
container.Register(
Component.For<IMyDao>()
.ImplementedBy<MyDao>()
.Named("myDao"),
//Components
Component.For<MyComponentObject>()
.Parameters(Parameter.ForKey("Dao").Eq("myDao")));
I put a break point where the code is bombing and also on the set of the property and DAO dependency is still null in my component and the set line of the property is actually never called.
Castle Windsor's setter injection simply does work properly.
[TestClass]
public class SetterInjectionTest
{
[TestMethod]
public void TestMethod1()
{
var container = new WindsorContainer();
container.Register(Component.For<IServiceB>().ImplementedBy<ServiceB>());
container.Register(Component.For<IServiceA>().ImplementedBy<ServiceA>());
var serviceA = container.Resolve<IServiceA>();
Assert.IsTrue(serviceA.IsPropertyInjected());
}
}
public class ServiceA : IServiceA
{
public IServiceB B { get; set; }
public bool IsPropertyInjected()
{
return B != null;
}
}
public interface IServiceA
{
bool IsPropertyInjected();
}
public class ServiceB : IServiceB{}
public interface IServiceB{}
Related
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.
I am writing a plugin as part of a plugin architecture. The way plugins are created is via reflection and CreateInstance. Therefore the default constructor is called. This code I cannot touch and I am trying to find a sensible way to use DI without the ability to use a framework.
I believe I have 3 options:
i) Poor Man's DI (PMDI)
ii) Factory Pattern
iii) TinyIOC or similar (one cs file that handles DI)
I started looking at PMDI but then a dependency needed another dependency so I ended up with something similar to this which is ugly and could get worse:
public MyMainPluginClass() : this(new Repo(new Logger()))
{
}
public MyMainPluginClass(IRepo repo)
{
}
I then moved onto the idea of a Factory Pattern but could not find any decent demo code. I assume I would have something like this:
public static FactoryUtility
{
public static IRepo GetRepo()
{
return new Repo(GetLogger());
}
public static ILogger GetLogger()
{
return new Logger();
}
}
public MyMainPluginClass() : this(FactoryUtility.GetRepo())
{
}
public MyMainPluginClass(IRepo repo)
{
}
Is that how it would look?
I then came across TinyIOC which is one class that does all the dependency registering but I believe it requires to be setup in a Program.cs which I don't have in a class library. If someone has any experience using this could it be used like so:
public MyMainPluginClass()
{
var container = TinyIoCContainer.Current;
container.AutoRegister();
var implementation = container.Resolve<IRepo>();
MyMainPluginClass(implementation);
}
public MyMainPluginClass(IRepo repo)
{
}
Are there any alternative approaches to achieve DI without using a 3rd party library and if not which approach would choose from above?
NOTE: The code above has not been compiled and is just an idea of what I think would work. Please post corrections if they are valid approaches.
Since you're using .NET 4, you might want to consider using MEF, as it's built into the framework itself. This looks like fairly straightforward DI, which MEF handles well, as it's intended mainly for extensibility.
For details, see the Learn More page on the MEF CodePlex site.
I went with TinyIOC in the end. Unfortunately the plugin's constructor gets called several times before its actually up and running. I simply set a boolean to prevent registration being called several times and therefore it allows me to simply auto-register dependencies and off we go.
public MyMainPluginClass() : this(FactoryUtility.SetupIOC())
{
}
public MyMainPluginClass(IRepo repo)
{
}
public static class FactoryUtility
{
private static bool Initialized = false;
public static IRepo SetupIOC()
{
var container = TinyIoCContainer.Current;
if (!Initialized)
{
container.AutoRegister(new[] { Assembly.GetExecutingAssembly() });
Initialized = true;
}
var result = container.Resolve<IRepo>();
return result;
}
}
If I absolutely don't want to add a dependency to a DI container, I like to use my own TinyIOC (sorry about the name, didn't know it was taken), which for small projects gives me the same semantics as using a container, but clocks in at below 200 LOC.
If you are interested, here is the code: https://gist.github.com/ad7608e2ae10b0f04229
I apologise for the length, and I know there are some answers on this but I searched a lot and haven't found the right solution,
so please bear with me.
I am trying to create a framework for legacy applications to use DI in ASP.NET webforms. I will probably use Castle Windsor
as the framework.
These legacy applications will use in part an MVP pattern in some places.
A presenter would look something like this:
class Presenter1
{
public Presenter1(IView1 view,
IRepository<User> userRepository)
{
}
}
Now the ASP.NET Page would look something like this:
public partial class MyPage1 : System.Web.UI.Page, IView1
{
private Presenter1 _presenter;
}
Before using DI I would instantiate the Presenter as follows in the OnInit of the page:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
_presenter = new Presenter1(this, new UserRepository(new SqlDataContext()));
}
So now I want to use DI.
First I must create a handler factory to override the construction of my page.
I found THIS really good answer to help:
How to use Dependency Injection with ASP.NET Web Forms
Now I can easily set up my containers in my composition root as Mark Seeman suggest to use the Global.asax
(This means though to create a static container that must be thread safe and sealed not to be able to add further registrations)
Now I can go and declare the constructor injection on the page
public MyPage1() : base()
{
}
public MyPage1(Presenter1 presenter) : this()
{
this._presenter = presenter;
}
Now we run into the first problem, I have a circular dependency.
Presenter1 depends on IView1, But the page depends on the presenter.
I know what some will say now that the design is probably incorrect when you have circular dependencies.
First I dont think the Presenter design is incorrect, by it taking a dependency in the constructor to the View, and I can say this
by looking at plenty of MVP implementations.
Some may suggest changing the Page to a design where Presenter1 becomes a property and then using Property injection
public partial class MyPage1 : System.Web.UI.Page, IView1
{
[Dependency]
public Presenter1 Presenter
{
get; set;
}
}
Some may even suggest removing the dependency to presenter completely and then simply Wiring up via a bunch of events, But this is
not the design I wanted and frankly dont see why I need to make this change to accomodate it.
Anyway regardless of the suggestion, another problem exists:
When the Handler factory gets a page request only a type is available (NOT THE VIEW INTERFACE):
Type pageType = page.GetType().BaseType;
now using this type you can resolve the Page via IoC and its dependencies:
container.Resolve(pageType)
This will then know that there is a property called Presenter1 and be able to inject it.
But Presenter1 needs IView1, but we never resolved IView1 through the container, so the container won't know
to provide the concrete instance the handler factory just created as it was created outside of container.
So we need to hack our handler factory and replace the view interface:
So where the handler factory resolves the page:
private void InjectDependencies(object page)
{
Type pageType = page.GetType().BaseType;
// hack
foreach (var intf in pageType.GetInterfaces())
{
if (typeof(IView).IsAssignableFrom(intf))
{
_container.Bind(intf, () => page);
}
}
// injectDependencies to page...
}
This poses another problem, most containers like Castle Windsor will not allow you to reregister this interface
to the instance it is pointing to now. Also with the container being registered in the Global.asax, it is not thread-safe to
do as the container should be read only at this point.
The other solution is to create a function to rebuild the container on each web request, and then check to see
if the container contains the component IView if not set the instance. But this seems wasteful and goes against suggested use.
The other solution is to create a special Factory called
IPresenterFactory and put the dependency in the page constructor:
public MyPage1(IPresenter1Factory factory) : this()
{
this._presenter = factory.Create(this);
}
The problem is that you now need to create a factory for each presenter and then make a call to the container
to resolve other dependencies:
class Presenter1Factory : IPresenter1Factory
{
public Presenter1Factory(Container container)
{
this._container = container;
}
public Presenter1 Create(IView1 view)
{
return new Presenter1(view, _container.Resolve<IUserRepository>,...)
}
}
This design also seems cumbersome and over complicated, does any one have ideas for a more elegant solution?
Perhaps I misunderstand your problems, but the solution seems fairly simple to me: promote the IView to a property on the Presenter1:
class Presenter1
{
public Presenter1(IRepository<User> userRepository)
{
}
public IView1 View { get; set; }
}
This way you can set the presenter on the view like this:
public Presenter1 Presenter { get; set; }
public MyPage1()
{
ObjectFactory.BuildUp(this);
this.Presenter.View = this;
}
Or without property injection, you can do it as follows:
private Presenter1 _presenter;
public MyPage1()
{
this._presenter = ObjectFactory.Resolve<Presenter1>();
this._presenter.View = this;
}
Constructor injection in Page classes and user controls will never really work. You can get it to work in full trust (as this article shows), but it will fail in partial trust. So you will have to call the container for this.
All DI containers are thread-safe, as long as you don't manually add registrations yourself after the initialization phase and with some containers even that is thread-safe (some containers even forbid registering types after initialization). There would never be a need to do this (except for unregistered type resolution, which most containers support). With Castle however, you need to register all concrete types upfront, which means it needs to know about your Presenter1, before you resolve it. Either register this, change this behavior, or move to a container that allows resolving concrete types by default.
I have a IUserService (and other services) that I am registering in bulk in my ServiceInstaller.cs:
container.Register(
AllTypes.FromAssemblyContaining<UserService>()
.Where(type => type.Name.EndsWith("Service"))
.WithService.DefaultInterface()
.Configure(c => c.LifeStyle.Singleton)
);
I then I have IAuthenticationService which I register as in my generic WindsorInstaller.cs file:
container.Register(Component.For(typeof (IAuthenticationService))
.ImplementedBy(typeof(AuthenticationService)));
Now things were working just fine until I added a public property for IAuthenticationService in my UserService.
It seems there is a circular dependacy or some timing issue of when things get registered, as I am getting the error:
Can't create component 'ABCD.Services.UserService' as it has dependencies to be satisfied.
ABCD.Services.UserService is waiting for the following dependencies:
Services:
- ABCD.Services.Interfaces.IAuthenticationService which was registered but is also waiting for dependencies.
ABCD.Services.AuthenticationService is waiting for the following dependencies:
Services:
- ABCD.Services.Interfaces.IUserService which was registered but is also waiting for dependencies.
How can I solve this issue?
You need to either:
Get rid of your circular dependencies (this is the preferred option), or
Work around them, by using property injection, rather than constructor injection.
Using property injection (as illustrated in Steven's answer) allows you to create instances of your classes without providing all the dependencies at the time of creation. The downside is that it is not as obvious to users of the class what they need to do to instantiate and fully configure the instance.
For a nice explanation of how to refactor to remove a ciruclar dependency see this blog post by Miško Hevery:
Circular Dependency in constructors and Dependency Injection
Property injection will solve your problem, because it breaks the dependency cycle. Just look at Krzysztof's example and try to instantiate a UserService; You can't. Now take a look at the following example:
public class UserService
{
UserService(AuthenticationService a) { }
}
public class AuthenticationService
{
AuthenticationService() { }
public UserService UserService { get; set; }
}
In this example, the UserService dependency of the AuthenticationService is 'promoted' from a constructor argument to a property. Now you can create a user service like this:
var a = new AuthenticationService();
var s = new UserService(a);
a.UserService = s;
Breaking the circular dependency can be done with property injection and any dependency injection framework can be configured to allow property injection.
here's your scenario as I understand it:
public class UserService
{
UserService(AuthenticationService a){}
}
public class AuthenticationService
{
AuthenticationService (UserService a){}
}
How would you create instances of both classes, creating at most single instance of each class?
I would like to just markup a property with an attribute [DoInjection] and have unity do the injection. I don't want to have to use prop = Unity.Resolve(type). Thats a pain and messy. Does unity provide attributes to do this or do I have to build my own?
Edit: register in App.Main
ISessionFactory sf = new SessionFactory();
container.RegisterType<IRepository, CustomerRepository>(new InjectionConstructor(sf.CurrentUoW));
container.RegisterInstance<IUnitOfWork>(sf.CurrentUoW);
Using [Dependancy] on IUnitOfWork propery in ClassX other class but it's always null. Do I need to build ClassX instance using Unity to get this to work? It looks like I do have to. I don't like that.
Unity has a DependencyAttribute you can use for this:
public class MyObject
{
private SomeOtherObject _dependentObject;
[Dependency]
public SomeOtherObject DependentObject
{
get { return _dependentObject; }
set { _dependentObject = value; }
}
}
http://msdn.microsoft.com/en-us/library/ff650198.aspx
Based on your question, it sounds like you might be trying to use Unity in the wrong spot and your design sense was telling you it didn't feel right. You should only see Unity where you bootstrap your application. That's your Main method in a console app or Global.asax in a web or wcf app. The idea is to keep relying on dependencies all the way up the chain until you get to where you bootstrap and resolve just that one top level object using your IoC container. In a console app, I do this:
class Program
{
static void Main(string[] args)
{
using (var container = new UnityContainer())
{
container
.AddExtension(new ConfigureForConsole(args))
.Resolve<MyApplication>()
.Execute();
}
}
}
http://www.agileatwork.com/console-application-with-ioc/
In this case, MyApplication is my top level object (it doesn't need to be an interface here). The ConfigureForConsole is just a one-off custom container extension that has all the RegisterType lines in there. Alternatively you could initialize the container from App.Config here. The idea though is that your Main method has almost nothing in it. Another benefit of this approach is that it makes your code more portable. I find that console apps usually turn into windows services and keeping things clean here makes that transition pretty painless.