问题描述
我有一个使用国际奥委会和DI创建和注入服务的应用程序。
我有一个处理一些业务逻辑的服务层,在我服务层与数据库通信的存储库。该存储库是使用的DataContext这不是线程安全的。
我要运行该服务的一些功能异步使用后台任务,但知道这会导致一些问题与存储库。因此,我要为创建的每个后台线程创建的存储库。这是如何实现的?我使用StructureMap国际奥委会
公共类服务:IService
{
IRepository _repository;
公共服务(IRepository库)
{
this._repository =库;
}
公共无效DoSomething的()
{
//做的工作
_repository.Save();
}
}
公共类控制器
{
IService _service;
公共控制器(IService服务)
{
this._service =服务;
}
公益行动DoSomethingManyTimes()
{
的for(int i = 0; I< numberOfTimes;我++)
{
Task.Factory.StartNew(()=>
{
_service.DoSomething();
});
}
}
}
有些DI容器(如(IIIRC)StructureMap)实际上支持的每个线程的一生的风格,但是这可能不会帮助你,因为它会注入 IService
到控制器
在一个线程,然后的使用的它在许多其他线程的。
我会建议什么是离开控制器
实现象,因为一个事实,即特定的实现 IService 不是线程安全的,是一个实现细节
相反,创建一个线程安全的 ,并注入到这一点控制器
。事情是这样的:
公共ThreadSafeService:IService
{
私人只读IServiceFactory厂;
公共ThreadSafeService(IServiceFactory工厂)
{
this.factory =厂;
}
公共无效DoSomething的()
{
this.factory.Create()DoSomething的()。
}
}
IServiceFactory
可以声明如下:
公共接口IServiceFactory
{
IService的Create();
}
如果您实施 IServiceFactory
所以它创建 IService的新实例
每次调用创建
,你有一个线程安全的实现另一方面,由于没有共享的状态。
这做法容器无关并防止漏抽象。
I have a application that uses IOC and DI to create and inject services.
I have a service layer that handles some business logic, in the service layer I have a repository that communicates with the database. That repository is using a DataContext which is not thread safe.
I want to run some functions on the service asynchronously using background tasks but know that this will cause issues with the repository. Thus I want the repository to be created for every background thread created. How is this achieved? I'm using StructureMap as the 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();
});
}
}
}
Some DI Containers (e.g. (IIIRC) StructureMap) actually support Per Thread lifetime styles, but that's probably not going to help you, because it would inject IService
into Controller
on one thread, and then use it on a number of other threads.
What I would suggest is to leave the Controller
implementations as is, because the fact that a particular implementation of IService
isn't thread-safe, is an implementation detail.
Instead, create a thread-safe Adapter/Decorator of IService
and inject that into Controller
. Something like this:
public ThreadSafeService : IService
{
private readonly IServiceFactory factory;
public ThreadSafeService(IServiceFactory factory)
{
this.factory = factory;
}
public void DoSomething()
{
this.factory.Create().DoSomething();
}
}
IServiceFactory
could be declared like this:
public interface IServiceFactory
{
IService Create();
}
If you implement IServiceFactory
so that it creates a new instance of IService
for every call to Create
, you have a thread-safe implementation on hand, because there's no shared state.
This approach is container-agnostic and prevents Leaky Abstractions.
这篇关于国际奥委会DI多线程的生命周期范围界定在后台任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!