Autofac与Web Api集成时出错

本文关键字:出错 集成 Api Web Autofac | 更新日期: 2023-09-27 18:06:25

我们的应用程序分为以下五个项目:

    一个只有Html页面的项目
  • 作为服务层的Web Api项目,只包含ApiController类
  • 业务层类库
  • 业务层契约类库,只包含接口
  • A数据层类库
  • 数据层契约类库,也只包含接口

WebApi服务包含对所有类库以及autofacc和AutofacWebApiDependencyResolver的引用。

我已经添加了必要的代码来注册容器和解析器,正如Autofac文档中所解释的那样:

    var builder = new ContainerBuilder();
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    var container = builder.Build();
    var resolver = new AutofacWebApiDependencyResolver(container);
    GlobalConfiguration.Configuration.DependencyResolver = resolver;

目前我有一个非常基本的依赖层次结构来测试它,如下所示:

//On the data contracts
public interface IData
{
   void SomeDataMethod();
}
//On the data layer
public class Data : IData
{
   public void SomeDataMethod(){}
}
//On the business contracts
public interface IBusiness
{
   void SomeBusinessMethod();
}
//On the business layer
public class Business : IBusiness
{
   private readonly IData _data;
   public Business(IData data)
   {
      _data = data;
   }
}
//On the Web Api project
[EnableCors("*", "*", "*")]
public class MyController : ApiController
{
   private IBusiness _business;
   public MyController(IBusiness business)
   {
      _business = business;
   }
}

所以这里没有什么高难度的东西但是当我运行这个项目时,我得到了以下错误:

 XMLHttpRequest cannot load http://localhost:61101/api/MyController. No
 'Access-Control-Allow-Origin' header is present on the requested
 resource. Origin 'http://localhost:56722' is therefore not allowed
 access.

如果我从控制器中删除构造函数,应用程序将正常工作,控制器将被实例化,并且它的get方法将被调用。

我做错了什么?

Autofac与Web Api集成时出错

显然,令人困惑的错误会导致你相信这确实是一个没有启用CORS的问题,这是由于使用Autofac Web Api集成程序集注册控制器的代码是不够的,你还需要手动注册所有其他程序集中的所有依赖项。

所以代码在全局。一个ax文件最终是这样的:

    var builder = new ContainerBuilder();
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
    var appAssemblies = assemblies.Where(a => a.ToString().StartsWith("MyCustomer.MyApplicationName") && !a.ToString().Contains("Services")).ToArray();
    builder.RegisterAssemblyTypes(appAssemblies).AsImplementedInterfaces();
    var container = builder.Build();
    var resolver = new AutofacWebApiDependencyResolver(container);
    GlobalConfiguration.Configuration.DependencyResolver = resolver;

这样做是因为我的每个程序集都是按照约定命名的:

CustomerName.ApplicationName.LayerName

所以我想要所有类型的我的应用程序程序集,除了服务的那些在Autofac注册。

看起来像是CORS问题。它可以像没有在Web API WebApiConfig.Register()函数中启用CORS一样简单吗?例如,您可以添加:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.EnableCors();
        // etc.
    }
}

将其与控制器的EnableCors属性组合。

或者,您可以全局启用CORS(而不仅仅是您的控制器),像这样:

var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);

请注意,限制您的CORS规则而不是到处使用"*"通常是良好/安全的做法。