在本人接触的项目中Autofac应用的比较多一些,我理解的他的工作原理就是 注册类并映射到接口,通过注入后返回相应实例化的类!
下面说说我在项目中的实际应用
先来简单介绍下Autofac的使用
1、通过Nuget或代码安装autofac
安装autofac :install-package autofac
安装对mvc4的支持:install -package autofac.mvc4(本人项目为mvc4)
2、新建相应的类及接口,并在autofac中进行映射
2.1、新建接口 INewsHelper
1
2
3
4
5
6
7
|
namespace
test.Interface
{
public
interface INewsHelper
{
string
GetNewInfo( int id);
}
}
|
2.2、新建类NewsHelper并继承INewsHelper
1
2
3
4
5
6
7
8
9
10
|
namespace
test.Helper
{
public
class NewsHelper:INewsHelper
{
public
string GetNewInfo( int id)
{
return
"newshelper" ;
}
}
}
|
2.3 新建类SubjectHelper并继承INewsHelper
1
2
3
4
5
6
7
8
9
10
11
|
namespace
test.Helper
{
public
class SubjectHelper:INewsHelper
{
public
string GetNewInfo( int id)
{
return
"subjecthelper" ;
}
}
}
|
2.4 在autofac中注册并映射
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
namespace
test
{
// 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
public
class MvcApplication : System.Web.HttpApplication
{
protected
void Application_Start()
{
var
builder = new ContainerBuilder();
builder.RegisterType<CategoryHelper>().As<ICategoryHelper>().InstancePerHttpRequest();
builder.RegisterType<NewsHelper>().Named<INewsHelper>(
"news"
);
builder.RegisterType<SubjectHelper>().Named<INewsHelper>(
"subject"
);
builder.RegisterControllers(Assembly.GetExecutingAssembly());
var
container = builder.Build();
DependencyResolver.SetResolver(
new
AutofacDependencyResolver(container));
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
}
}
}
|
3、新建ServiceGetter类及 IServiceGetter接口
3.1
1
2
3
4
5
6
7
|
namespace
test.Interface
{
public
interface IServiceGetter
{
T GetByName<T>(
string
name);
}
}
|
3.2
1
2
3
4
5
6
7
8
9
10
|
namespace
test.Helper
{
public
class ServiceGetter:IServiceGetter
{
public
T GetByName<T>( string name)
{
return
AutofacDependencyResolver.Current.RequestLifetimeScope.ResolveNamed<T>(name);
}
}
}
|
3.3 增加注册
1
|
builder.RegisterType<ServiceGetter>().As<IServiceGetter>();
|
整个步骤3做了一件事,给中间件一个某个泛型的name,由中间件向autofac要相应的class的实例并返回给我,说白了就是干了下面这句代码的事
1
|
AutofacDependencyResolver.Current.RequestLifetimeScope.ResolveNamed<INewsHelper>(
"news"
);
|
4、通过构造函数进行注入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
namespace
test.Controllers
{
public
class HomeController : Controller
{
private
IServiceGetter getter;
public
HomeController(IServiceGetter getter)
{
this
.getter = getter;
}
public
ActionResult Index()
{
ViewBag.Message = getter.GetByName<INewsHelper>(
"subject"
).GetNewInfo(1);
return
View();
}
}
}
|
Q:为什么没有在HomeController的构造函数中直接就取回呢?
A:应为这个时候我们还不知道具体需要那个实例,所以要在需要的时候通过getter再取回来。
这样就完成了整个对于一个接口多个实现并定义多个Name的情况下,如何通过构造函数注入的方式来实现。
看下实际的效果:
情况1:
效果1:
情况2:
效果2: