Autofac在項目中應用的體會,一個接口多個實現的情況


在本人接觸的項目中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:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM