|
|
I am wanting to resolve dependencies across a chain with parameters.
ie.
Client-> ModelObject -> BusinessObject -> DataObject
client get's model from container
on the DataObjects constructor it takes a parameter, ie. ctor DataObject(string id)
When I get the ModelObject, how do I tell Unity to pass a value, ie. "1" to the DataObject construction in this chain ?
I don't want any references to DataObject in my Client, just ModelObject
End result:
Model.GetData() -> BusinessObject.GetData() -> DataObject.Execute() - uses that 'id' to retrieve the data
|
|
|
|
You don't. At least not directly.
You could specify named dependencies, so that client depends on <ModelObject, "SpecificObject">, and that depends on <BusinessObject, "SpecificObject">, and
that depends on <DataObject, "SpecificObject">. That one is configured to be constructed with a particular ID.
However, I would suggest that this is the wrong way to use a DI container. DI is best used to supply services, not domain entities. I would suggest that client should get a ModelObjectRepository injected. That repository knows how to figure out which model
to hook up. The Model could also get a BusinessObjectRepository (or just have the code in it directly).
I'll have to cook up a bigger example, but I hope this gives you the gist of what I'm saying.
-Chris
|
|
|
|
Thanks Chris.
I'm basing some of my idea on the following MSDN article:
http://msdn2.microsoft.com/en-us/library/aa973811.aspx
The only real difference between my particular setup and that article setup is that I have a data structure that needs to be provided several levels deep to the constructor of that object.
ie.
1 IRepository<Order>repository =
new ValidatingOrderRepository(
new SecurityRepository<Order>(
new LoggingRepository<Order>(
new CachingRepository<Order>(
new NHibernateRepository<Order>()))));
2 Order order = repository.Get(35);
I do have some state I'm passing through the layers.
My alternative is to goto the container at each step manually ?
I know that Windsor allows to pass a dictionary with a key, where that key would be matching that parameter
public DataObject(string id)...
When I create the model, this is passed along the chain?
pseudo code...
Hashtable ht = new Hashtable();
ht.Add("id", "35");
Model model = container<Model>.Get("Model1", ht);
When the container is resolving the dependencies and encounters a match of DataObject 'id' to the hashtable 'id' it would override the default id value with the value from the hashtable.
That would be what I would hope for here. Whether I use Repository, Dao, etc... I still need to have some values passed down to an underlying dependency.
Maybe I'm off in my thinking, but this is what I'm picturing - to me, this would be a great feature to have for Unity
|
|
|
|
Below is an example of setting up a decorator chain. In my example, the IMyService that is injected into
MyApplication is MyServiceImpl decorated by MyServiceDecorator
[Test]
public void MyServiceIsDecorated()
{
MyApplication a = container.Resolve<MyApplication>();
int result = a.Compute(2, 3);
Assert.AreEqual(result, 10);
}
public class MyApplication
{
private IMyService myService;
public MyApplication(IMyService myService)
{
this.myService = myService;
}
public int Compute(int x, int y)
{
return myService.Compute(x, y);
}
}
public interface IMyService
{
int Compute(int x, int y);
}
public class MyServiceImpl : IMyService
{
public int Compute(int x, int y)
{
return x + y;
}
}
public class MyServiceDecorator : IMyService
{
private IMyService myService;
public MyServiceDecorator(IMyService myService)
{
this.myService = myService;
}
public int Compute(int x, int y)
{
return myService.Compute(x, y) * 2;
}
}
<unity>
<containers>
<container>
<types>
<type
name="MyServiceImpl"
type="UnityConfigExample.IMyService, UnityConfigExample"
mapTo="UnityConfigExample.MyServiceImpl, UnityConfigExample"/>
<type
type="UnityConfigExample.IMyService, UnityConfigExample"
mapTo="UnityConfigExample.MyServiceDecorator, UnityConfigExample">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
<constructor>
<param name="myService" parameterType="UnityConfigExample.IMyService, UnityConfigExample">
<dependency name="MyServiceImpl"/>
</param>
</constructor>
</typeConfig>
</type>
</types>
</container>
</containers>
</unity>
|
|