Autofac 依賴注入 ASP.NET MVC5 插件機制中插件的簡單實現
一.前言
由於項目業務復雜,創建了多個插件並把他們放在了不同的項目中,項目使用AutoFac做的IOC;但是主項目可以注入,插件注入失敗,
沒有為該對象定義無參數的構造函數。下面就一步一步注入插件項目。
二.新建帶有插件的項目
項目結構如下圖:

三.建立DomainServices類庫
新建一個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數據";
}
}
}
四.autofac實現主項目注入和插件注入
1.主項目引用autofac、autofac.Integration.Mvc
工具->庫程序包管理器->管理解決方案的NuGet程序包:

2.主項目新建一個AutoFacBootStrapper.cs類,實現autofac注入
代碼如下:
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();
}
}
}
五.測試autofac注入是否成功
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的數據如下:

插件:


