Autofac在项目中应用的体会一个接口多个实现的情况

发布时间 2023-08-07 12:03:16作者: 大西瓜3721

在本人接触的项目中Autofac应用的比较多一些,我理解的他的工作原理就是  注册类并映射到接口,通过注入后返回相应实例化的类

下面说说我在项目中的实际应用

先来简单介绍下Autofac的使用

1、通过Nuget或代码安装autofac

安装autofac :install-package autofac 

安装对mvc4的支持:install -package autofac.mvc4(本人项目为mvc4)

2、新建相应的类及接口,并在autofac中进行映射

2.1、新建接口 INewsHelper

复制代码
namespace test.Interface
{
    public interface INewsHelper
    {
        string GetNewInfo(int id);
    }
}
复制代码

2.2、新建类NewsHelper并继承INewsHelper

复制代码
namespace test.Helper
{
    public class NewsHelper:INewsHelper
    {
        public string GetNewInfo(int id)
        {
            return "newshelper";
        }
    }
}
复制代码

2.3 新建类SubjectHelper并继承INewsHelper

复制代码
namespace test.Helper
{
    public class SubjectHelper:INewsHelper
    {
        public string GetNewInfo(int id)
        {
            return "subjecthelper";
        }
 
    }
}  
复制代码

2.4 在autofac中注册并映射

复制代码
namespace test
{
    // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
    // 请访问 http://go.microsoft.com/?LinkId=9394801
 
    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

复制代码
namespace test.Interface
{
    public interface IServiceGetter
    {
         T GetByName<T>(string name);
    }
}  
复制代码

3.2

复制代码
namespace test.Helper
{
    public class ServiceGetter:IServiceGetter
    {
        public T GetByName<T>(string name)
        {
            return AutofacDependencyResolver.Current.RequestLifetimeScope.ResolveNamed<T>(name);
        }
    }
}
复制代码

3.3 增加注册

builder.RegisterType<ServiceGetter>().As<IServiceGetter>();

整个步骤3做了一件事,给中间件一个某个泛型的name,由中间件向autofac要相应的class的实例并返回给我,说白了就是干了下面这句代码的事

AutofacDependencyResolver.Current.RequestLifetimeScope.ResolveNamed<INewsHelper>("news");

4、通过构造函数进行注入

复制代码
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: