Dependency Injection with Static classes and properties
I have designed a multi-layer solution and created a bunch of Manager classes to implement Business Logic. All the managers are derived from BaseManager
class. To be more clear, here's UserManager
class:
public class UserManager : BaseManager
{
public void Add(User user)
{
...
}
public void Update(User user)
{
...
}
public void Delete(User user)
{
...
}
public bool GetAccessPermissions(User user)
{
...
}
}
BaseManager
is as follows:
public class BaseManager
{
protected IRepository repository = IoCLocator.Resolve<IRepository>();
public BaseManager()
{
...
}
// Some shared methods among manager classes.
}
Now I skeptical that my manager classes should all be defined static, since they get their related entities on which they want to operate, as paramet开发者_开发技巧ers. But As you see, I have some shared private/protected members which I should instantiate upon every call. (e.g. repository
should be instantiated on each manager class's creation).
What are my choices to define managers classes as static and still have the protected members instantiated on each call to managers' methods?
Do you need your manager classes to be static, or is it just that you wish them to be singletons?
Are you seeking a way to have a singleton class with transient dependencies?
In which case I would answer that the singleton manager class should take a dependency on a factory which can create instances of the repositories as required.
Windsor offers a typed factory facility which helps with creating such factories: http://docs.castleproject.org/Windsor.Typed-Factory-Facility-interface-based-factories.ashx
You have several options here:
1)
public class BaseManager
{
protected IRepository repository;
public BaseManager(IRepository _repository)
{
repository = _repository
}
// Some shared methods among manager classes.
}
This requires you to instantiate your BaseManager using
IoCLocator.Resolve<BaseManager>();
or something like that, depending on concrete IoCLocator
(MEF, Unity, Ninject or whatever you are using)
2) Pretty much the same:
public class BaseManager
{
protected IRepository repository;
public BaseManager(IoCLocator locator)
{
repository = locator.Resolve<IRepository>();
}
// Some shared methods among manager classes.
}
3) Or, inject the property directly
public class BaseManager
{
[InjectFromContainer]
protected IRepository repository {get;set;}
public BaseManager()
{
repository = locator.Resolve<IRepository>();
}
// Some shared methods among manager classes.
}
I cannot exactly name the Attribute you need, because it depends on your container.
Anyway, you'll have to instantiate IoC Container in BootStrapper, register BaseManager
with it and then resolve its instance from the container.
Hope this helps, Ilya
UPDATE:
Your concept is just a mess. Static classes which you want to inherit, IoC Container working with main application classes being static. I'd recommend you to choose one of each, and the problem will be gone by itself.
精彩评论