Asp.Net DDD架構(gòu)淺談——依賴注入Autofac

本系列目錄

Asp.Net DDD架構(gòu)淺談——整體框架說明
Asp.Net DDD架構(gòu)淺談——領(lǐng)域劃分、倉儲應(yīng)用、Services層定義
Asp.Net DDD架構(gòu)淺談——圖片上傳、縮略裁剪
Asp.Net DDD架構(gòu)淺談——依賴注入Autofac
Asp.Net DDD架構(gòu)淺談——網(wǎng)站配置

控制反轉(zhuǎn)(Inversion of Control,縮寫為IoC)是開發(fā)中的一種設(shè)計模式,可以理解為面向接口編程,可以有效的降低耦合度。舉個例子,看我們的解決方案圖:


Steven.Domain

我們把Repsositories和Services的接口都定義在Steven.Domain里面,而實現(xiàn)是單獨的項目Steven.Domain.Repositories和Steven.Domain.Services。
為什么要這么麻煩呢? 合在一起不好嗎?
合在一起的話耦合度太高,如果要換ORM會很麻煩,比如說我現(xiàn)在在Steven.Domain.Repositories中用的是Dapper,而如果我想轉(zhuǎn)用EntityFramework,我只要新建一個項目Steven.Domain.EFRepositories,然后在新項目中實現(xiàn)接口即可,對于Presentation層來說,沒有任何改變,因為在Presentation層我們調(diào)用的是接口。

Autofac

Autofac是一個開源的依賴注入框架,使用也非常簡單,首先是通過NuGet安裝:

Autofac

然后創(chuàng)建一個配置類DependencyConfig,在里面做好接口配置

    public class DependencyConfig
    {
        public static void Register()
        {
            var builder = new ContainerBuilder();

            builder.RegisterControllers(Assembly.GetCallingAssembly())//注冊mvc的Controller
                .PropertiesAutowired();//屬性注入
            builder.RegisterGeneric(typeof(Repository<>))
                .As(typeof(IRepository<>))
                .InstancePerRequest()//每次http請求
                .PropertiesAutowired();//屬性注入

            //Repositories的注入
            builder.RegisterAssemblyTypes(typeof(UsersRepository).Assembly)
                .Where(t => t.Name.EndsWith("Repository"))
                .AsImplementedInterfaces()
                .InstancePerRequest()
                .PropertiesAutowired();
 
            //Services的注入
            builder.RegisterAssemblyTypes(typeof(FormsAuthenticationSvc).Assembly)
                .Where(t => t.Name.EndsWith("Svc"))
                .AsImplementedInterfaces()
                .InstancePerRequest()
                .PropertiesAutowired();

            //Cache的注入,使用單例模式
            builder.RegisterType<RedisCacheManager>()
                .As<ICacheManager>()
                .SingleInstance()
                .PropertiesAutowired();
            
            var container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        }
    }

然后再Global.asax中配置,Application_Start網(wǎng)站啟動的時候進行配置:

DependencyConfig.Register();

如何使用呢?非常簡單, 我們打開HomeController看下:

    public class HomeController : WebSiteController
    {
        public IArticleRepository ArticleRepository { get; set; }

        public ActionResult Index()
        {
            var list = ArticleRepository.GetAll();
            return View(list);
        }

        public ActionResult Detail(string id)
        {
            var article = ArticleRepository.GetByIndex(id);
            if (article == null)
            {
                return Redirect(Url.Home());
            }
            //update view count
            ArticleRepository.UpdateViewCount(article.Id);
            return View(article);
        }
    }

只需要定義一個屬性即可:public IArticleRepository ArticleRepository { get; set; } 是不是非常簡單!
上面用到的是屬性注入的方式,回過頭了看下DependencyConfig類的定義,每個配置后面都有這么一句代碼:PropertiesAutowired(),這就是表示使用屬性配置。而在以前,我使用構(gòu)造函數(shù)注入,下面讓我們來看下構(gòu)造函數(shù)注入有什么不同:
首先是DependencyConfig的配置,把PropertiesAutowired()刪掉即可,然后是使用到接口的地方,比如說HomeController:

    public class HomeController : WebSiteController
    {
        private readonly IArticleRepository ArticleRepository;
        public HomeController(IArticleRepository articleRepository)
        {
            ArticleRepository = articleRepository;
        }

        public ActionResult Index()
        {
            var list = ArticleRepository.GetAll();
            return View(list);
        }

        public ActionResult Detail(string id)
        {
            var article = ArticleRepository.GetByIndex(id);
            if (article == null)
            {
                return Redirect(Url.Home());
            }
            //update view count
            ArticleRepository.UpdateViewCount(article.Id);
            return View(article);
        }
    }

屬性變成了私有變量,并且在HomeController的構(gòu)造函數(shù)中傳一個參數(shù)過來賦值。這種方式稍顯麻煩,個人意見。

注意事項

依賴注入的兩個類中不能互相依賴,比如說我們在ARepository中用到了IBRepository,那么就不能再BRepository里面注入IARepository,這樣會無限循環(huán),導(dǎo)致異常。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容