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

时间:2017-03-20 06:55:06

标签: c# dependency-injection asp.net-web-api2 owin autofac

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

ProjectA - Owin Selfhost Webapi应用

ProjectB - 类库应用程序(参考项目A)此处添加了WebApi控制器

ProjectB控制器在ProjectA中通过覆盖DefaultAssembliesResolver解决,如here所述。

ProjectA代码:

//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>();
  }
}

ISSUE:

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

  

尝试创建类型的控制器时发生错误   &#39; DemoController&#39 ;.确保控制器具有无参数   公共建设者。

问题

1)我解决外部装配中依赖关系的方法是否正确?还有更好的选择吗?

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

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

1 个答案:

答案 0 :(得分:0)

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

解决了这个问题

1)创建一个类并使用Module类进行扩展并覆盖Load方法。在重写方法中注册依赖项。

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>);

就是这样。快乐的编码!