Autofac - 解决单独程序集的 Web Api 控制器中的依赖关系

Autofac - Resolve dependencies in WebApi controllers of seperate assemblies

我在 visual studio 解决方案中有两个项目

ProjectA - Owin Selfhost Webapi 应用程序

ProjectB - A Class Library Application (References ProjectA) WebApi controllers are added here

ProjectB 控制器通过重写 DefaultAssembliesResolver 在 ProjectA 中解析,如 here 所述。

项目代码:

//WebApi startup class
public class Startup
{
  public void Configuration(IAppBuilder app)
  {

   var config = new HttpConfiguration();
   config.Services.Replace(typeof(IAssembliesResolver), new MyAssemblyResolver());

   var builder = new ContainerBuilder();

   var assemblies = GetExternalControllerAssemblier();
   assemblies.Add(Assembly.GetExecutingAssembly());

   builder.RegisterApiControllers(assemblies.ToArray());

   //Builder reference is passed to external controllers and builder object is updated there
   HandleExtControllerDependency(ref builder, assemblies);

   var container = builder.Build();
   config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
   app.UseAutofacMiddleware(container);
   app.UseAutofacWebApi(config);
  }
}

//I'm using reflection and calling a method in external assembly, to update `builder` object.
private void HandleExtControllerDependency(ref builder, List<Assembly> assemblies)
{
   foreach (component in assemblies)
   {
      var type = assembly.GetType(component+"DependencyHandler");
      IDependencyHandler handler = Activator.CreateInstance(type) as IDependencyHandler;
      handler.LoadDependencies(ref builder);
   }
}

项目 B 代码: 从 ProjectA 传递的 builder 对象将在此处更新。

public class DependencyHandler : IDependencyHandler
{
  public void LoadDependencies(ref ContainerBuilder builder)
  {
      builder.RegisterType<Demo>().As<IDemo>();
  }
}

问题:

我有一个名为 DemoController 的控制器,并且有一个无参数构造函数。我期待 AutoFac 注入依赖项。似乎依赖关系没有在控制器中解决。我收到以下错误:

An error occurred when trying to create a controller of type 'DemoController'. Make sure that the controller has a parameterless public constructor.

问题

1) 我解决外部程序集依赖的方法是否正确?有没有更好的选择?

2) 我需要这个代码吗? builder.RegisterApiControllers(assemblies.ToArray());

3) 我该如何解决这个问题?

Autofac 提供了一种简单的机制来实现我的要求。我已经使用 AutoFac Assembly Scanning.

解决了这个问题

1) 创建一个class 并用Module class 扩展并覆盖Load 方法。在 Overridden 方法中注册依赖项。

public class AModule : Module
{
  protected override void Load(ContainerBuilder builder)
  {
    builder.Register(c => new AComponent()).As<AComponent>();
  }
}

public class BModule : Module
{
  protected override void Load(ContainerBuilder builder)
  {
    builder.Register(c => new BComponent()).As<BComponent>();
  }
}

2) 在主应用程序中注册模块:

var assembly = typeof(AComponent).Assembly;
var builder = new ContainerBuilder();

// Registers both modules
builder.RegisterAssemblyModules(assembly);

注意: 不要忘记通过调用

注册外部控制器
builder.RegisterApiControllers(<assembly array>);

就是这样。编码愉快!