I have this (fictional) desktop application which allows project managers to search for idle developers and assign tasks. The model is:
interface IDeveloperFactory
{
IDeveloper CreateDeveloper(string name);
}
interface IDeveloper
{
void WriteCode();
void WriteUnitTest();
}
interface ITask
{
void Complete();
}
class Developer : IDeveloper
{
public Developer(string name) { ... }
public void WriteCode()
{
Console.WriteLine("Developer {0} is writing code... done", name);
}
public void WriteUnitTest()
{
Console.WriteLine("Developer {0} is writing unit test... done", name);
}
}
class WriteCodeTask : ITask
{
public Task(Lazy<IDeveloper> lazyDeveloper) { ... }
public void Complete()
{
var dev = lazyDeveloper.Value;
dev.WriteCode();
}
}
Developer
has a runtime dependency so I will use DeveloperFooFactory
(which is configured as typed factory) to get IDeveloper
's. While a IDeveloper
is in use I also need ITask
's which use the developer instance and my work would be much easier if I could just ask the container to resolve them:
var developerFactory = container.Resolve<IDeveloperFactory>();
var dev1 = developerFactory.CreateDeveloper("dev 1");
var task1 = container.Resolve<ITask>();
task1.Complete(); // uses dev1
var task2 = container.Resolve<ITask>();
task2.Complete(); // uses dev1
container.Release(dev1); // also releases task1 and task2
var dev2 = developerFactory.CreateDeveloper("dev 2");
var task3 = container.Resolve<ITask>();
task3.Complete(); // uses dev2
// task1, task2 and task3 are always different instances
Questions:
- How can I configure the container to achieve this? (I intend to use version 3.0)
- Ideally I would not release
dev1
before creatingdev2
(e.g. createdev
's at the same time on different threads) but I still need the container to resolveITask
's properly... Do I need to use child containers for this, or maybe the newBeginScope
method in 3.0? - It is also possible that a developer can handle multiple tasks at once, on different threads. So whenever I need a task I would just ask the container to resolve it and use the "contextual developer" instance... but how?
I am aware things might be easier if it were not for the circular dependency. However it seems that the model, the real one I mean, is more natural this way...