最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#在MEF框架中手動(dòng)導(dǎo)入依賴模塊

 更新時(shí)間:2022年06月22日 10:55:24   作者:天方  
這篇文章介紹了C#在MEF框架中手動(dòng)導(dǎo)入依賴模塊的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

對(duì)于簡(jiǎn)單的場(chǎng)景來(lái)講,在MEF中導(dǎo)入依賴模塊非常簡(jiǎn)單,只要用ImportAttribute標(biāo)記依賴的成員,MEF模塊會(huì)自動(dòng)找到并創(chuàng)建該模塊。但有的時(shí)候我們依賴的模塊是上下文相關(guān)的,此時(shí)MEF框架的自動(dòng)組裝滿足不了我們的需求了,這里以我之前的文章的一個(gè)Log插件為例:

    class HostModule
    {
        [Import]
        ILogger logger = null;

        public string Name { get; private set; }

        public HostModule(string name)
        {
            this.Name = name;
            Compose();

            logger.LogMessage("hello world");
        }

        void Compose()
        {
            var catalog = new AssemblyCatalog(this.GetType().Assembly);
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }
    }

    interface ILogger
    {
        void LogMessage(string msg);
    }

    [Export(typeof(ILogger))]
    class ConsoleLogger : ILogger
    {
        public void LogMessage(string msg)
        {
            Console.WriteLine(DateTime.Now + ": " + msg);
        }
    }

現(xiàn)在我想要在Log信息中加入模塊名稱作為前綴,改成如下形式:

    [Export(typeof(ILogger))]
    class ConsoleLogger : ILogger
    {
        public string ModuleName { get; private set; }

        public void LogMessage(string msg)
        {
            Console.WriteLine(">> " + ModuleName + " | " + DateTime.Now + ": " + msg);
        }
    }

由于MEF框架不知道Logger.ModuleName和HostModule.Name的關(guān)系,無(wú)法直接通過(guò)ImportAttribute標(biāo)記ModuleName屬性搞定。那么,我們?cè)撊绾蝹魅脒@ModuleName呢?

通過(guò)構(gòu)造函數(shù)導(dǎo)入:

這最直接想到的就是一種方式了,主要修改如下:

  • 在插件模塊中創(chuàng)建構(gòu)造函數(shù),參數(shù)為需要導(dǎo)入的依賴模塊,并且用ImportingConstructorAttribute標(biāo)記構(gòu)造函數(shù)。

  • 在構(gòu)造函數(shù)中庸ImportAttribute標(biāo)記參數(shù)

  • 在組裝函數(shù)中用ComposeExportedValue函數(shù)傳入?yún)?shù)

示例代碼如下:

    class HostModule
    {
        [Import]
        ILogger logger = null;

        public string Name { get; private set; }

        public HostModule(string name)
        {
            this.Name = name;
            Compose();

            logger.LogMessage("hello world");
        }

        void Compose()
        {
            var catalog = new AssemblyCatalog(this.GetType().Assembly);
            var container = new CompositionContainer(catalog);
            container.ComposeExportedValue("ModuleName", this.Name);
            container.ComposeParts(this);
        }
    }

    interface ILogger
    {
        void LogMessage(string msg);
    }

    [Export(typeof(ILogger))]
    class ConsoleLogger : ILogger
    {
        public string ModuleName { get; private set; }

        [ImportingConstructor]
        public ConsoleLogger([Import("ModuleName")] string moduleName)
        {
            this.ModuleName = moduleName;
        }

        public void LogMessage(string msg)
        {
            Console.WriteLine(">> " + ModuleName + " | " + DateTime.Now + ": " + msg);
        }
    }

這種方式一個(gè)比較大的缺點(diǎn)就是麻煩,上面的例子還好,如果要導(dǎo)入的參數(shù)比較多就顯得有點(diǎn)麻煩了。并且后續(xù)要新增一個(gè)依賴的模塊的話則要同時(shí)修改好幾處處地方,不夠集中,容易改漏,并且也不容易排查錯(cuò)誤。

在成員中導(dǎo)入

在成員中導(dǎo)入的方式如下:

  • 在Host中用Export標(biāo)記導(dǎo)出參數(shù)

  • 在插件模塊中用Import標(biāo)記導(dǎo)入?yún)?shù)

修改后的代碼如下,我把修改的地方標(biāo)記了一下:

    class HostModule
    {
        [Import]
        ILogger logger = null;

        [Export("ModuleName")]
        public string Name { get; private set; }

        public HostModule(string name)
        {
            this.Name = name;
            Compose();

            logger.LogMessage("hello world");
        }

        void Compose()
        {
            var catalog = new AssemblyCatalog(this.GetType().Assembly);
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }
    }

    interface ILogger
    {
        void LogMessage(string msg);
    }

    [Export(typeof(ILogger))]
    class ConsoleLogger : ILogger
    {
        [Import("ModuleName")]
        public string ModuleName { get; private set; }

        public void LogMessage(string msg)
        {
            Console.WriteLine(">> " + ModuleName + " | " + DateTime.Now + ": " + msg);
        }
    }

這種方式改動(dòng)更少更直觀,擴(kuò)展性也更強(qiáng),要好用得多了。

進(jìn)一步解除限制

前面這種方式非常方便,但有一個(gè)限制:功能模塊是由MEF框架在組裝的時(shí)候創(chuàng)建的。但是,有的時(shí)候,功能模塊無(wú)法由MEF框架創(chuàng)建(例如在WPF程序中的UI對(duì)象,或者一些比較復(fù)雜的上下文相關(guān)對(duì)象),但是,這個(gè)時(shí)候我們?nèi)绾问謩?dòng)導(dǎo)入依賴的外部模塊呢?MEF框架本身也是提供了比較完善的解決方案的:在執(zhí)行ComposeParts函數(shù)組裝的時(shí)候?qū)蓚€(gè)對(duì)象一并傳入一起組裝即可。

    class HostModule
    {
        ILogger logger = new ConsoleLogger();

        [Export("ModuleName")]
        public string Name { get; private set; }

        public HostModule(string name)
        {
            this.Name = name;
            Compose();

            logger.LogMessage("hello world");
        }

        void Compose()
        {
            var container = new CompositionContainer();
            container.ComposeParts(this, logger);
        }
    }

    interface ILogger
    {
        void LogMessage(string msg);
    }

    class ConsoleLogger : ILogger
    {
        [Import("ModuleName")]
        public string ModuleName { get; private set; }

        public void LogMessage(string msg)
        {
            Console.WriteLine(">> " + ModuleName + " | " + DateTime.Now + ": " + msg);
        }
    }

小結(jié):雖然前面介紹的這三種方式看起來(lái)有不小差別,但歸根結(jié)底只是不同的組裝形式而已,只要掌握了MEF的組裝原理,就可以非常自由的組裝我們所需要的模塊,實(shí)現(xiàn)松耦合、簡(jiǎn)單化、模塊化的程序。

到此這篇關(guān)于C#在MEF框架中手動(dòng)導(dǎo)入依賴模塊的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解C#?wpf如何嵌入hwnd窗口

    詳解C#?wpf如何嵌入hwnd窗口

    wpf是Direct?UI,窗口中只有一個(gè)hwnd句柄,大部分控件都是直接在上面繪制的,本文主要來(lái)和大家講講如何嵌入hwnd窗口,感興趣的可以了解一下
    2024-03-03
  • 關(guān)于C#線程的全面解析

    關(guān)于C#線程的全面解析

    這篇文章主要介紹了關(guān)于C#線程的全面解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • C#窗體間通訊的幾種常用處理方法總結(jié)

    C#窗體間通訊的幾種常用處理方法總結(jié)

    這篇文章主要介紹了C#窗體間通訊的幾種常用處理方法總結(jié),有很好的實(shí)用價(jià)值,需要的朋友可以參考下
    2014-08-08
  • Unity Shader相交算法實(shí)現(xiàn)簡(jiǎn)易防能量盾

    Unity Shader相交算法實(shí)現(xiàn)簡(jiǎn)易防能量盾

    這篇文章主要為大家詳細(xì)介紹了Unity Shader相交算法實(shí)現(xiàn)簡(jiǎn)易防能量盾,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • winform用datagridview制作課程表實(shí)例

    winform用datagridview制作課程表實(shí)例

    這篇文章主要介紹了winform用datagridview制作課程表的方法,實(shí)例分析了WinForm實(shí)現(xiàn)課程表的結(jié)構(gòu)、數(shù)據(jù)庫(kù)及調(diào)用技巧,需要的朋友可以參考下
    2015-01-01
  • C#中SQL Command的基本用法

    C#中SQL Command的基本用法

    今天小編就為大家分享一篇關(guān)于C#中SQL Command的基本用法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-10-10
  • WPF在VisualTree上增加Visual

    WPF在VisualTree上增加Visual

    這篇文章介紹了WPF在VisualTree上增加Visual的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • Unity解析gif動(dòng)態(tài)圖操作

    Unity解析gif動(dòng)態(tài)圖操作

    這篇文章主要介紹了Unity解析gif動(dòng)態(tài)圖操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • C#與java TCP通道加密通信實(shí)例

    C#與java TCP通道加密通信實(shí)例

    這篇文章主要介紹了C#與java TCP通道加密通信,文章通過(guò)真實(shí)的案例詳細(xì)講解說(shuō)明C#與java TCP通道加密通信的相關(guān)資料,需要的小伙伴可以參考一下
    2021-10-10
  • Stream.Write 與 StreamWriter.Write 的不同

    Stream.Write 與 StreamWriter.Write 的不同

    Stream.Write 與 StreamWriter.Write 是我們?cè)谙蛄髦袑?xiě)數(shù)據(jù)時(shí),最常用的方法。下面就詳細(xì)講解這兩個(gè)方法。
    2013-04-04

最新評(píng)論

迁安市| 阿荣旗| 三明市| 浦北县| 灵武市| 广西| 全州县| 凌源市| 香河县| 荃湾区| 禄劝| 灵武市| 平武县| 成武县| 霍邱县| 印江| 丁青县| 仁化县| 龙海市| 察哈| 吐鲁番市| 鄂托克旗| 从江县| 贵溪市| 海原县| 芦溪县| 沽源县| 西平县| 井陉县| 长沙县| 吉木乃县| 光泽县| 巴楚县| 宝清县| 和田县| 延寿县| 蒙山县| 临夏县| 平阴县| 大竹县| 毕节市|