C# Autofac与Web Api集成时出错

C# Autofac与Web Api集成时出错,c#,asp.net-web-api,autofac,C#,Asp.net Web Api,Autofac,我们的申请分为以下五个项目: 仅包含Html页面的项目 Web Api项目,其功能为服务层,仅包含ApiController类 业务层类库 仅包含接口的业务层协定类库 数据层类库 数据层合同类库也只包含接口 Web Api服务包含对所有类库以及Autofac和AutoFacWebAPI依赖解析程序的引用 我已经添加了注册容器和解析器所需的代码,如Autofac文档中所述: var builder = new ContainerBuilder(); builder.Regist

我们的申请分为以下五个项目:

  • 仅包含Html页面的项目
  • Web Api项目,其功能为服务层,仅包含ApiController类
  • 业务层类库
  • 仅包含接口的业务层协定类库
  • 数据层类库
  • 数据层合同类库也只包含接口
Web Api服务包含对所有类库以及Autofac和AutoFacWebAPI依赖解析程序的引用

我已经添加了注册容器和解析器所需的代码,如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方法将被调用


我可能做错了什么?

看起来像是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);
    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;

请注意,通常最好/安全的做法是限制CORS规则,而不是使用
“*”
无处不在。

显然,令人困惑的错误会让您认为CORS未启用确实是一个问题,这是由于向Autofac Web Api集成程序集注册控制器的代码不够,您还需要手动注册所有其他程序集中的所有依赖项

因此Global.asax文件中的代码是这样的:

var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
    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已启用。正如我所说的,如果我删除了具有依赖关系的构造函数,那么应用程序将正常工作,控制器将被实例化,其中一个Get方法将被调用,而不会出现任何问题。