Reputation: 10251
I have a class with a DAL dependency:
public class FirstClass()
{
[Dependency]
public IDalType Dal { get; set; }
}
I can create an instance of the class with:
UnityContainer c = new UnityContainer();
c.RegisterType<IDalType, DalType>();
FirstClass fc = c.Resolve<FirstClass>();
This will set the dependency and I can use the instance. This is something like a starting main class (main form, main ViewModel).
Now, I have a SecondClass
again with a DAL dependency and that second class must be instantiated and called from the first class. How do I do that?
public class FirstClass()
{
[Dependency]
public IDalType Dal { get; set; }
public DoSomething()
{
??? SecondClass sc = App.UnityContainer.Resolve<SecondClass>();
}
}
If I use the UnityContainer inside the first class, that will be a coupling with the container, and I will have to map IDAL -> DAL somewhere in application root and have a static container.
I read that coupling with the container is bad, as well as using static map: http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx
Upvotes: 0
Views: 262
Reputation: 6806
Using a factory will put some knowledge about the instantiation of a service (your SecondClass
) inside your consumer. In this post Mark Seemann describes another approach.
And if you don't want to waste time and effort coding those type of adapters have a look at the TecX project on CodePlex. It adds support for generating lazy proxies on-the-fly using Unity.
Upvotes: 1
Reputation: 30401
Add SecondClass as a dependency of FirstClass:
public class FirstClass
{
[Dependency]
public IDalType Dal { get; set; }
[Dependency]
public SecondClass Sc { get; set; }
public DoSomething()
{
sc.DoWhatever();
}
}
However, I'd strongly recommend switching to constructor injection instead:
public class FirstClass
{
private IDalType dal;
private SecondClass sc;
public FirstClass(IDalType dal, SecondClass sc)
{
this.dal = dal;
this.sc = sc;
}
public DoSomething()
{
sc.DoWhatever();
}
}
This way you aren't coupled to the container via the attributes, and you aren't exposing properties that are only there as inputs (confusing your class's public interface), and you guarantee you can't create an instance of FirstClass without it having all the dependencies it needs.
UPDATE
If you need to create the instance on demand, you can instead inject Func. Unity will create a factory method for you that, when invoked, will call back into the container.
public class FirstClass
{
private IDalType dal;
private Func<SecondClass> scFactory;
public FirstClass(IDalType dal, Func<SecondClass> scFactory)
{
this.dal = dal;
this.scFactory = scFactory;
}
public DoSomething()
{
SecondClass cs = scFactory();
sc.DoWhatever();
}
}
If you have more complex requirements to choose which helper object does what, I'd reevaluate if you should be getting the object in question from the container at all. Instead, consider injecting an explicit factory object instead.
Upvotes: 1