后台任务中的 IOC DI 多线程生命周期范围

2023-11-22

我有一个使用 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();
           });
       }
    }
}

一些 DI 容器(例如(IIIRC)StructureMap)实际上支持每线程生命周期风格,但这可能不会帮助你,因为它会注入IService into Controller在一个线程上,然后use它在许多其他线程上。

我的建议是离开Controller实现原样,因为事实上,一个特定的实现IService不是线程安全的,是一个实现细节。

相反,创建一个线程安全的适配器/装饰器 of IService并将其注入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,您手头有一个线程安全的实现,因为没有共享状态。

这种方法是与容器无关的并防止抽象泄漏。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

后台任务中的 IOC DI 多线程生命周期范围 的相关文章