国际奥委会DI多线程的生命周期范围界定在后台任务 [英] IOC DI Multi-Threaded Lifecycle Scoping in Background Tasks

查看:233
本文介绍了国际奥委会DI多线程的生命周期范围界定在后台任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用国际奥委会和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 <中/ code>不是线程安全的,是一个实现细节



相反,创建一个线程安全的 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多线程的生命周期范围界定在后台任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆