我有一个使用IOC和DI来创建和注入服务的应用程序。
我有一个处理某些业务逻辑的服务层,在服务层我有一个与数据库通信的存储库。该存储库使用的是一个非线程安全的DataContext。
我想使用后台任务异步运行服务上的一些函数,但是知道这会导致存储库出现问题。因此,我希望为每个创建的后台线程创建存储库。这是如何实现的?我使用StructureMap作为IoC。
public class Service : IService
{
IRepository _repository;
public Service(IRepository repository)
{
this._repository = repository;
}
public void DoSomething()
{
// Do Work
_repository.Save();
}
}
public class Controller
{
IService _service;
public Controller(IService service)
{
this._service = service;
}
public Action DoSomethingManyTimes()
{
for(int i =0; i < numberOfTimes; i++)
{
Task.Factory.StartNew(() =>
{
_service.DoSomething();
});
}
}
}
答案 0 :(得分:7)
一些DI容器(例如(IIIRC)StructureMap)实际上支持 Per Thread 生命周期样式,但这可能无法帮助你,因为它会注入IService
Controller
在一个线程上,然后在许多其他线程上使用。
我建议保留Controller
实现,因为IService
的特定实现不是线程安全的,这是一个实现细节。
相反,请创建IService
的线程安全Adapter/Decorator并将其注入Controller
。像这样:
public ThreadSafeService : IService
{
private readonly IServiceFactory factory;
public ThreadSafeService(IServiceFactory factory)
{
this.factory = factory;
}
public void DoSomething()
{
this.factory.Create().DoSomething();
}
}
IServiceFactory
可以这样声明:
public interface IServiceFactory
{
IService Create();
}
如果您实施IServiceFactory
以便为IService
的每次调用创建Create
的新实例,那么您手头就有一个线程安全的实现,因为那里有没有共享状态。
此方法容器无关,可防止漏洞抽象。