Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在多线程应用程序(Decorator或Interceptor?)中正确使用IOC_C#_Multithreading_Dependency Injection_Ioc Container - Fatal编程技术网

C# 在多线程应用程序(Decorator或Interceptor?)中正确使用IOC

C# 在多线程应用程序(Decorator或Interceptor?)中正确使用IOC,c#,multithreading,dependency-injection,ioc-container,C#,Multithreading,Dependency Injection,Ioc Container,我正在用一种非常类似的方法来做这个项目,就像中的那个。我使用Unity作为DI框架,对此我很陌生。 有一个JobController,它应该在新任务中启动注入服务n次。代码看起来与Chads最初发布的代码几乎相同 public class Controller { IService _service; public Controller(IService service) { this._service = service; } public Ac

我正在用一种非常类似的方法来做这个项目,就像中的那个。我使用Unity作为DI框架,对此我很陌生。 有一个JobController,它应该在新任务中启动注入服务n次。代码看起来与Chads最初发布的代码几乎相同

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();
         });
      }
   }
}
我对此有几个问题:

  • 代码不是干巴巴的。我不想为我的每个服务编写ThreadSafeService装饰程序。而且我也不想为我的每项服务都有一个新的ServiceFactory
  • my ServiceFactorys的实现必须知道如何创建具体的服务,但由于这些服务作为内部类存储在另一个程序集中,并且还具有其他必须注入的依赖项(到存储库等),我不知道工厂应该放在哪里,也不知道如何使用Unity创建具有所有依赖关系的具体服务 在观看了Marks之后,我试图通过实现Unity拦截器来解决第一个问题,如下所示:

    internal class ThreadSafeServiceInterceptor : IInterceptionBehavior
    {
        IServiceFactory serviceFactory;
    
        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {           
            serviceFactory.Create().Start();
            return getNext()(input, getNext);
        }
    
        ...
    }
    
    serviceFactory是通过构造函数注入的。除了我仍然没有找到问题2的好解决方案之外,我如何才能告诉Unity必须将哪个具体的SessionFactory注入我的拦截器?这取决于启动的服务。目前在我的应用程序中,我做了如下操作:

    public ThreadSafeService1 : IService
    {
       private readonly IServiceFactory factory;
    
       public ThreadSafeService1(IServiceFactory factory)
       {
           this.factory = factory;
       }
    
       public void DoSomething()
       {
           this.factory.Create().DoSomething();
       }
    }
    
    internal class Service1Factory : IServiceFactory
    {
        public IService Create()
        {
            return new Service1();
        }
    }
    
    var service = container.Resolve<IService>("Service1");
    var controller = container.Resolve<JobController>(new ParameterOverride("service", service));
    
     controller.StartWork();
    

    但我想并行处理几个单元。这就是为什么我认为我需要几个具体服务的实例

    我会这样做

    public class Controller
    {
        Func<IService> _factory;
    
    public Controller(Func<IService> factory)
    {
       _factory = factory;
    }
    
    public Action DoSomethingManyTimes()
    {
      for(int i =0; i < numberOfTimes; i++)
      {
         Task.Factory.StartNew(() =>
         {  
            _factory().DoSomething();
         });
      }
    }
    }
    
    Func<string,IService>
    
    公共类控制器
    {
    Func_工厂;
    公共控制器(Func工厂)
    {
    _工厂=工厂;
    }
    公共行动DoSomethingManyTimes()
    {
    for(int i=0;i
    {  
    _工厂();
    });
    }
    }
    }
    
    任何像样的DI容器都应该知道如何解析Func(我不使用Unity,默认情况下autofac会这样做)。因此,您为您的服务注入了一个工厂,然后每个任务都有自己的服务实例

    我通常在单例存储库中使用这种方法,在这里我注入一个DbConnection工厂或我需要的任何东西,然后每个方法将使用不同的实例,并且没有共享状态

    更新 服务工厂可以是一个抽象的工厂,因此您没有为每个服务创建一个工厂,而是为所有服务创建一个工厂。也许是这样的

    public class Controller
    {
        Func<IService> _factory;
    
    public Controller(Func<IService> factory)
    {
       _factory = factory;
    }
    
    public Action DoSomethingManyTimes()
    {
      for(int i =0; i < numberOfTimes; i++)
      {
         Task.Factory.StartNew(() =>
         {  
            _factory().DoSomething();
         });
      }
    }
    }
    
    Func<string,IService>
    
    Func
    

    并且您将Unity设置为只注入工厂方法(来自您的服务工厂类)。该工厂可以封装Unity来创建实际的服务

    我会考虑降低您试图开发的内容的复杂性。这看起来像是一个项目,你试图应用技术是为了学习,而不是为了解决问题。谢谢你的回复。我在我的第一个问题中评论说,因为我这里没有足够的字符。我想就是这样!刚刚测试过将Func注入我的Unity控制器。非常感谢你!