I'm trying to solve a IoC problem, that seemed easy at first, but turned out to be a pain in the ass:-P
I have a heavy weight main class, which must be initialized only once, so it's marked as Singleton. However this class uses a subclass which must be created once for each request, so it's marked as Transient:
public class MyRegistry : Registry
{
public MyRegistry()
{
For<IMainClass>()
.Singleton()
.Use(ctx => new MainClass(() => ctx.GetInstance<ISubClass>()));
For<ISubClass>()
.Transient()
.Use(ctx => CreateNewInstanceOfSubClass());
}
private ISubClass CreateNewInstanceOfSubClass()
{
return new SubClass();
}
}
public interface ISubClass
{ }
public class SubClass : ISubClass
{ }
public interface IMainClass
{ }
public class MainClass : IMainClass
{
private readonly Func<ISubClass> _subClassProvider;
public MainClass(Func<ISubClass> subClassProvider)
{
_subClassProvider = subClassProvider;
}
public void DoStuff()
{
var requestSpecificInstanceOfSubClass = _subClassProvider();
// ...
}
}
As you can see, I pass a lambda to the constructor of MainClass
, which is used to get an instance of ISubClass
. During debugging I could definitely see that ctx.GetInstance<ISubClass>()
is executed each time MainClass
needs a SubClass
instance. But to my surprise, SubClass
is only created once as a singleton, instead of being created for each request.
However, when I call container.GetInstance<ISubClass>()
directly from somewhere within my code the behavior is exactly as desired. SubClass
is created once and only once for each request.
I'm no quite sure, but I guess the problem comes from the context object that is passed to the lambda, which is the context of a singleton(?). But I really don't know how to get the desired behavior here!?
I hope you can help me with this one. Thanks for your answers.
Regards, Dante
MainClass
need to be initialized? At application startup? At first usage? – KatherineMainClass
must be initialized at application startup. Actually the class itself is not too complicated. But it creates and manages a TCP socket. So it's absolutely crucial that this class is only created once. I agree, that constructors must be as simple as possible. In this case I must find a way to create a new instance ofSubClass
for each request without creating newMainClass
instances. So that's a bit tricky. – Mouflon