在 ASP .Net MVC 5 和 Web Api 2 项目之间配置 IoC



根据另一篇文章的答案,我正在尝试为ASP .Net MVC 5项目和Web Api 2项目配置autofac。

对于Web Api项目,我使用了Autofac.Integration.WebApi库,我手动将其引用到项目中,并修改了Global.asax文件,如下所示:

public class WebApiApplication : HttpApplication
{
    protected void Application_Start()
    {
        ConfigureDiContainer();
        GlobalConfiguration.Configure(WebApiConfig.Register);
    }
    private static void ConfigureDiContainer()
    {
        var servicesAssembly = Assembly.GetExecutingAssembly();
        var container = BuildContainer(servicesAssembly);
        var resolver = new AutofacWebApiDependencyResolver(container);
        GlobalConfiguration.Configuration.DependencyResolver = resolver;
    }
    private static IContainer BuildContainer(Assembly servicesAssembly)
    {
        var x = new ActivityBl();
        var builder = new ContainerBuilder();
        builder.RegisterApiControllers(servicesAssembly);
        var appAssemblies = AppDomain.CurrentDomain
            .GetAssemblies()
            .Where(a => a.ToString().StartsWith("SC."))
            .ToArray();
        builder.RegisterAssemblyTypes(appAssemblies).AsImplementedInterfaces();
        builder.RegisterAssemblyTypes(servicesAssembly).AsImplementedInterfaces();
        return builder.Build();
    }
}

当我运行服务时,这按预期工作。

对于MVC 5项目,我从NuGet安装了Autofac.Integration.Mvc库,并修改了Global.asax代码:

public class MvcApplication : HttpApplication
{
    protected void Application_Start()
    {
        var builder = new ContainerBuilder();
        builder.RegisterControllers(typeof(MvcApplication).Assembly);
        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}

两个项目中的控制器都没有默认构造函数,只有具有依赖项的构造函数:

MVC 控制器:

    private readonly IActivitiesService activitiesService;
    public HomeController(IActivitiesService activitiesService)
    {
        this.activitiesService = activitiesService;
    }

网页 API 控制器:

public class ActivitiesController : ApiController, IActivitiesService
{
    private readonly IActivities activitiesBl;
    public ActivitiesController(IActivities activitiesBl)
    {
        if(activitiesBl == null) throw new ArgumentNullException("activitiesBl", "ActivitiesBl dependency was not properly created.");
        this.activitiesBl = activitiesBl;
    }
}

当我运行应用程序时,出现以下错误:

没有找到任何构造函数 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type '唰唰唰。Web.Controllers.HomeController' 可以使用可用的 服务和参数:无法解析参数 '唰唰唰。服务.服务合同.IA活动服务' 构造函数 'Void .ctor(SC.服务.服务合同.IActivities服务)'。

在某种程度上,我想这是有道理的,因为 Web 项目上的 IoC 没有服务的定义,并且似乎它正在尝试解决整个依赖树,这导致我遇到以下问题:

  1. 从库的名称来看,似乎每个库都是专门为每种项目量身定制的,是这样还是我可以将 Mvc 也用于 Web API?
  2. 事情是否发生了变化,以至于我从上一篇文章中得到的建议不再有效,现在我必须在每个客户端的合成根中拥有所有定义?
  3. 现在,在这种多层设置中配置依赖项层次结构的最佳方法是什么?

谢谢。

我有许多来自多个项目的常见依赖项,包括Web Api(使用Web Api Autofac集成),Quartz Scheduling,单元测试,数据迁移控制台应用程序等。

为此,我已经能够以项目预期的方式启动 ContainerBuilder,然后我只需将其传递到单独项目中存在的一些代码中以指定共享依赖项。

您可能有以下 3 个项目

MyApp.WebApi

var builder = new ContainerBuilder();
builder.RegisterApiControllers(servicesAssembly);
CommonContainerConfig.RegisterDependencies(builder);

MyApp.Mvc5

var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
CommonContainerConfig.RegisterDependencies(builder);

MyApp.Common

public static class CommonContainerConfig
{
    public static void RegisterDependencies(ContainerBuilder builder) 
    {
        builder.RegisterType<ActivitiesService>().As<IActivitiesService>();
        //etc
    }
}

这适用于我的场景,尽管我不是 100% 确定这就是您所追求的......

最新更新