使用带有Autofac的.Net核心库实现插件系统

时间:2017-11-24 12:13:47

标签: c# asp.net autofac autofac-module

几个月前,我在ASP.Net Core 1.1中构建了一个非常简单但仍然有效的插件系统,其中包含autofac模块

在startup.cs中

public IServiceProvider ConfigureServices(IServiceCollection services)
{
  var builder = new ContainerBuilder();
  builder.RegisterModule<AutofacModule>();
  builder.Populate(services);
  var ApplicationContainer = builder.Build();
  return new AutofacServiceProvider(ApplicationContainer);
}

然后在AutofacModule.cs

protected override void Load(ContainerBuilder builder)
    {
        base.Load(builder);
        builder.RegisterType<AuthMessageSender>().As<IEmailSender>();
        builder.RegisterType<AuthMessageSender>().As<ISmsSender>();
        builder.RegisterType<HttpClient>().As<HttpClient>();
        foreach (var assembly in LoadAllAssemblies())
        {
            builder.RegisterAssemblyModules(assembly);
        }
    }

    private IEnumerable<Assembly> LoadAllAssemblies()
    {
        string assemblyPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "");
        var allAssemblies = new List<Assembly>();
        foreach (string dll in Directory.GetFiles(assemblyPath, "*.dll"))
        {
            try
            {
                var assembly = Assembly.LoadFile(dll);
                if (!assembly.GetTypes().Any(type => type.IsSubclassOf(typeof(Autofac.Module))))
                {
                    continue;
                }
                allAssemblies.Add(assembly);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                continue;
            }
        }
        return allAssemblies;
    }

然后我可以从这样的程序集中加载模块:

    public class AutofacModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        base.Load(builder);
        builder.RegisterType<UserService>().As<IUserService>();
        builder.RegisterType<DashboardService>().As<IDashboardService>();
        builder.RegisterType<DetailPageService>().As<IDetailPanelService>();
        builder.RegisterType<PlanningService>().As<IPlanningService>();
        builder.RegisterType<PlanningRepository>().As<IPlanningRepository>();     
    }
}

我必须将程序集复制到正在运行的Web app bin目录才能工作,或者引用主Web项目中的所有程序集。所有程序集都是.Net Framework类库。 过了一会儿,我将整个解决方案更新到Asp.Net Core 2.0,并将包含程序集的Autofac模块更改为.Net Core Class Libraries。现在,仍然可以找到autofac模块,并通过RegisterAssemblyModules注册,但不再调用load方法。我意识到,如果我使用autofac模块创建另一个.Net Framework库项目并引用它,它仍然按预期加载,并调用load方法。所以在我看来这个问题与.Net核心库有关。

任何人都可以解释这一点,知道任何解决方案,解决方法,或者可以为autofac的插件系统推荐另一种架构吗?

0 个答案:

没有答案