一.前言html
因爲項目業務複雜,建立了多個插件並把他們放在了不一樣的項目中,項目使用AutoFac作的IOC;可是主項目能夠注入,插件注入失敗,web
沒有爲該對象定義無參數的構造函數。下面就一步一步注入插件項目。app
參考:ASP.NET MVC5 插件化機制簡單實現asp.net
項目結構以下圖:函數
新建一個ITestService接口,代碼以下:工具
namespace DomainServices { public interface ITestService { string GetData(); string GetMainData(); } }
新建一個TestService類實現ITestService,代碼以下:測試
namespace DomainServices { public class TestService:ITestService { public string GetData() { return "這是插件獲取的Services數據"; } public string GetMainData() { return "這是主項目獲取的Services數據"; } } }
1.主項目引用autofac、autofac.Integration.Mvcui
工具->庫程序包管理器->管理解決方案的NuGet程序包:spa
2.主項目新建一個AutoFacBootStrapper.cs類,實現autofac注入.net
代碼以下:
using System.IO; using System.Linq; using System.Reflection; using System.Web; using System.Web.Mvc; using Autofac; using Autofac.Integration.Mvc; namespace Web { public class AutoFacBootStrapper { public static void AutoFacInit() { var builder = new ContainerBuilder(); //註冊DomainServices var services = Assembly.Load("DomainServices"); builder.RegisterAssemblyTypes(services, services) .Where(t => t.Name.EndsWith("Service")) .AsImplementedInterfaces().PropertiesAutowired(); //實現插件Controllers注入 var assemblies = new DirectoryInfo( HttpContext.Current.Server.MapPath("~/App_Data/Plugins/")) .GetFiles("*.dll") .Select(r => Assembly.LoadFrom(r.FullName)).ToArray(); foreach (var assembly in assemblies) { builder.RegisterControllers(assembly).PropertiesAutowired(); } //註冊主項目的Controllers builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired(); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); } } }
3.啓用autofac注入,在Global程序Start的地方添加AutoFacBootStrapper.AutoFacInit();
using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; namespace Web { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //啓用autofac注入 AutoFacBootStrapper.AutoFacInit(); } } }
1.主web的HomeController給出構造函數注入demo
using System.Web.Mvc; using DomainServices; namespace Web.Controllers { public class HomeController : Controller { //public ITestService Service { get; set; } ITestService _service; public HomeController(ITestService service) { _service = service; } public ActionResult Index() { ViewBag.Show = _service.GetMainData(); return View(); } } }
主項目的View代碼:
@{ ViewBag.Title = "Home Page"; } <div class="jumbotron"> <h1>ASP.NET</h1> <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p> <p><a href="http://asp.net" class="btn btn-primary btn-large">Learn more »</a></p> </div> <div class="row"> <p>這裏是autofac注入的主項目:@ViewBag.Show </p> @Html.ActionLink("Demo插件內容訪問點擊這裏", "Index", "Home", new { area = "Demo" }, null) </div>
2.插件的HomeControllers給出一個屬性注入demo
注意:autofac官網不建議使用屬性注入,爲了便於演示,我在AutoFacBootStrapper也加上了屬性注入了。具體項目的時間建議使用構造函數注入的方式。
using System.Web.Mvc; using DomainServices; namespace Plugin.Demo.Controllers { public class HomeController : Controller { public ITestService Service { get; set; } public ActionResult Index() { ViewBag.Show=Service.GetData(); return View(); } } }
插件的View代碼:
<div> <p>ASP.NET MVC 插件化:Plugin.Demo 內容</p> <p>autofac注入插件:@ViewBag.Show</p> </div>
3.從新生成插件,運行主項目,效果以下:
主項目頁面autofac注入成功後調用DomainServices的數據以下:
插件: