I read a bunch of questions and all docs at Ninject wiki, but I still doubt and ask questions to myself like "Am I doing it right?"
A) So I need something like this:
public class MyClass : IMyInterface
{
private string _field;
readonly IRepository _repo;
public MyClass(string field, IRepository repo)
{
_field = field;
_repo = repo;
}
}
But how to Bind it properly? Or should I forever forget about using constructor for any reason but Constructor Dependency Injection?
B) And do it like:
public class MyClass : IMyInterface
{
private string _field;
readonly IRepository _repo;
public MyClass(IRepository repo)
{
_repo = repo;
}
public void Initialize(string field)
{
_field = field;
}
}
I think it isn't ok to call anytime when I need object this Initialize function or I'm wrong?
According to this answers Can't combine Factory / DI and Dependency Inject (DI) "friendly" library and Is there a pattern for initializing objects created via a DI container
Use Abstract Factory if you need a short-lived object
Dependencies injected with Constructor Injection tend to be long-lived, but sometimes you need a short-lived object, or to construct the dependency based on a value known only at run-time.
C) I should do it like:
public interface IMyInterface { }
public interface IMyFactory
{
MyClass Create(string field);
}
public class MyFactory : IMyFactory
{
private readonly IRepository _repo;
public MyFactory (IRepository repo)
{
_repo = repo;
}
public MyClass Create(string field)
{
return new MyClass(_repo, field);
}
}
public class MyClass : IMyInterface
{
private string _field;
readonly IRepository _repo;
public MyClass(IRepository repo, string field)
{
_repo = repo;
_field = field;
}
}
And if I need MyClass from another class I gonna use it like
public class OtherClass
{
private IMyInterface _myClass;
public OtherClass(IMyFactory factory)
{
_myClass = factory.Create("Something");
}
}
Isn't it too bulky?
And my question is: What I have to use A, B or C case? And why? Or maybe something else?
What if I need to use controller for initialization of object? And field argument will be known only at runtime?
As explained here, your application components should not require runtime data during initialization. Instead you should either:
Contrary to popular belief, abstract factories are hardly ever the right solution to this problem, because:
Instead of lowering complexity for the consumer, a factory actually increases complexity, because instead of having just a dependency on the service abstraction IService, the consumer now requires a dependency on both IService and the Abstract Factory IServiceFactory. [...] the increase in complexity can be felt instantly when unit testing such classes. Not only does this force us to test the interaction the consumer has with the service, we have to test the interaction with the factory as well.
For a detailed discussion, read this article.