如何使用Simple Injector到Azure Worker角色

时间:2017-06-08 16:47:00

标签: c# azure azure-worker-roles simple-injector

我引用了几个文档,但我需要正确的实现才能正确执行。

参考

  1. Unity to Worker角色:https://alexandrebrisebois.wordpress.com/2013/04/14/building-windows-azure-services-without-compromising-testability/

  2. 控制台应用的SimpleInjector:http://simpleinjector.readthedocs.io/en/latest/consoleintegration.html

  3. 我的问题

    1. 参考-1,Unity使用using (var uc = new UnityContainer()){...}但SimpleInjector有ThreadScopedLifestyleAsyncScopedLifestyle。我使用哪一个?

    2. 参考-2有static Main类,static readonly Containerstatic contructor。我是否为工作人员角色定义static Container?那么依赖注册的static constructor呢?

    3. 我实现如下我的实施部分。此代码是否正确实现?

    4. 参考代码

      参考文献1;

      static class Program
      {
          static readonly Container container;
      
          static Program()
          {
              container = new Container();
      
              container.Register<IUserRepository, SqlUserRepository>();
              container.Register<MyRootType>();
      
              container.Verify();
          }
      
          static void Main()
          {
              var service = container.GetInstance<MyRootType>();
              service.DoSomething();
          }
      }
      

      参考文献2;

      public class WorkerRole : RoleEntryPoint
      {
       public override void Run()
       {
           // This is a sample worker implementation. Replace with your logic.
           Trace.WriteLine("Worker entry point called", "Information");
      
           using (var uc = new UnityContainer())
           {
               uc.RegisterType<ILogger, TableStorageLogger>();
               uc.RegisterType<IEnumerable<IMessageHandler>, IMessageHandler[]>();
      
               var processor = uc.Resolve<MessageProcessor>();
      
               while (true)
               {
                   processor.Process();
                   Thread.Sleep(10000);
                   Trace.WriteLine("Working", "Information");
               }
           }
       }
      

      我的实施

      我认为(1)Container足以成为static,(2)OnStart是注册服务的好地方,(3)我打算创建服务实例,每个循环都处理掉。

      public class WorkerRole : RoleEntryPoint
      {
          static readonly Container container = new Container();
      
          public override void Run()
          {
              while (true)
              {
                  using (ThreadScopedLifestyle.BeginScope(container))
                  {
                      var service = container.GetInstance<SomeService>();
                      service.DoSomething();
                  }
              }
          }
      
          public override bool OnStart(){
              // define.
              container.Register<SomeService>();
              container.Register<ProcessRecorderSetting>();
              container.Verify();
          } 
      }
      

      注意:我不知道上面的代码是否正常工作。

1 个答案:

答案 0 :(得分:1)

  

参考-1,Unity使用(var uc = new UnityContainer()){...}但SimpleInjector使用ThreadScopedLifestyle或AsyncScopedLifestyle。我使用哪一个?

如果我没有弄错的话,Azure辅助工作者角色是一个短暂的应用程序,开始做一件简单的事情,而不是快速死亡,就像使用控制台应用程序一样。

考虑到DI,这使得Worker角色的开发与Console应用程序的开发非常相似。这意味着:

  • 该应用程序是短暂的
  • 只运行一个请求(与在Web服务/应用程序中并行运行多个请求相比)
  • 需要注册一组限制依赖项。

这意味着,由于应用程序是单线程且短暂的,因此不需要使用范围的生活方式(例如ThreadScopedLifestyleAsyncScopedLifestyle)。相反,您可以轻松地将所有依赖项注册为单例,解析根,调用其方法,并处置容器。

但是,如果您的应用程序存在很长时间,并且无休止地循环,您通常希望模拟“请求”的概念。这通常意味着每个循环都是一个请求,并在该请求期间从容器中解析。请注意,如果您实际拥有范围注册,则只需要一个范围的生活方式。如果没有,您不必将请求包装在范围内。如果您具有作用域注册,则必须将每个请求包装在作用域中,就像您在示例中所做的那样。

  

Reference-2具有静态Main类,静态readonly Container和静态构造函数。我是否为Worker角色定义静态容器?那么依赖注册的静态构造函数呢?

虽然静态构造函数可以免费提供线程安全和单例行为,但是如果抛出异常,它们确实会使调试复杂化,因为实际错误包含在TypeInitializationException中。但是,您的cctor确实可以轻松初始化静态Container字段。将Container置于静态字段中可以。

但是,由于这些类型的应用程序非常小,只有一小部分依赖项,因此容器在所有中使用DI容器。而是使用Pure DI。这可能听起来像是开发和维护DI容器的人的一个奇怪的建议,但我发现将Pure DI用于小型应用程序更为实际,特别是当你的寄存器都是单身的时候。优点是:

  • 您对构建对象图表有编译时支持
  • 它可以防止必须使用第三方工具
  • 对于应用程序的初始化阶段,DI容器有很多开销,而工作者角色应该快速启动。
  • 小对象图可以相当容易。