多个 Autofac 组件共享的应用程序范围初始化的最佳实践? (在这种情况下提供许可证。)

Best practice for application-wide initialization shared by several Autofac components? (Aspose license in this case.)

我们正在使用 Autofac,并且我们的一些组件使用需要许可证的 Aspose 库。许可证是这样加载的:

   public class MyAutofacModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            // [Register stuff]
            LoadAsposeLicense();
        }

        private void LoadAsposeLicense()
        {
            // Load the Aspose license.
            string licenseFile = Path.Combine(Assembly.GetExecutingAssembly().Location, "..", "Aspose.Total.lic");
            Aspose.Slides.License license = new Aspose.Slides.License();
            license.SetLicense(licenseFile);
        }
    }

我认为这是个好主意,直​​到我想从一些不需要 Aspose 功能的代码中重用 DLL。我们拥有所有 Aspose 产品的许可证,但现在,我们只使用 PowerPoint 的东西。但是,将来可能会发生变化,我们可能会有其他组件需要 Word 功能。许可证应该是一样的,但我想它必须单独初始化。

我想知道引入一个像这样的简单许可证组件是否有意义,它会被注册为一个单例(或者我可以更懒惰并将代码放入静态构造函数中):

    class AsposeSlidesLicense
    {
        public AsposeSlidesLicense()
        {
            string licenseFile = Path.Combine(Assembly.GetExecutingAssembly().Location, "..", "Aspose.Total.lic");
            Aspose.Slides.License license = new Aspose.Slides.License();
            license.SetLicense(licenseFile);
        }
    }

然后我可以像这样使用它:

    class MyComponentThatUsesAspose : ISlidesCreatorService
    {
        public MyComponentThatUsesAspose(AsposeSlidesLicense license)
        {
            // Dummy constructor to make sure the license is loaded
        }

        public void CreateSlide()
        {
            // Use Aspose library
        }
    }

但由于 license 依赖项(参数)除了触发许可证加载外没有其他功能,我有点担心,它可能被编译器、Resharper 或其他开发人员优化掉了。

所以我的问题是:

放置这样的初始化代码的最佳位置是什么,多个组件可能需要这样的代码才能有 运行 once? 并且仅在需要这些服务时(实例化组件)?

到运行代码当一个组件被请求时你可以使用OnActivatingautofac lifetime event

您可以在注册时监听此类事件,每次请求组件时,都会触发此事件。

builder.RegisterType<LicenseVerifier>()
       .As<ILicenseVerifier>()
       .SingleInstance()


builder.RegisterType<YourComponent>()
       .OnActivating(e => e.Context.Resolve<ILicenseVerifier>().EnsureLicense())

在您的 EnsureLicense 中,您可以做任何您想做的事情来确保应用许可证。

如果您有很多组件,将 OnActivating 调用包装到自定义方法扩展并编写如下内容可能是个好主意:

builder.RegisterType<YourComponent>()
       .WithLicense()

另一种选择是将属性添加到 YourComponent

[RequireLicense]
public class YourComponent {}

并创建一个 autofac 模块,它将 OnActivating 部分添加到具有该属性的所有组件中。


如果您想在应用程序启动时运行编码,Autofac 有两种机制。

  • 您可以实现 IStartable 它是一个 Autofac 接口,在构建容器时 运行。

      public class StartupMessageWriter : IStartable
      {
        public void Start()
        {
          Console.WriteLine("App is starting up!");
        }
      }
    

    并像这样注册:

      builder
       .RegisterType<StartupMessageWriter>()
       .As<IStartable>()
       .SingleInstance();
    
  • 您可以使用 AutoActivate 注册组件。在这种情况下,将在构建容器时构建组件

      builder
        .RegisterType<TypeRequiringWarmStart>()
        .AsSelf()
        .AutoActivate();
    
  • 您也可以创建自己的接口并在容器初始化后解决这些问题。

您可以在 running code at container build 文档中找到有关 autofac 的更多信息。