小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

C#插件開(kāi)發(fā)簡(jiǎn)單模型

 ThinkTank_引擎 2014-10-09
一、前言 

插件模型指應(yīng)用程序由一些動(dòng)態(tài)的獨(dú)立模塊構(gòu)成,每個(gè)模塊均具有一個(gè)或多個(gè)服務(wù),并滿足一定的插件協(xié)議,能夠借助主程序?qū)崿F(xiàn)主程序-插件,插件-插件之間的通訊。它定義了一套公共的接口,通過(guò)接口與插件進(jìn)行通信,主要是通過(guò)反射來(lái)獲取相關(guān)的屬性和方法,然后再執(zhí)行指定的操作。其實(shí),它也可以理解為定義一套通用的解決方案,通過(guò)反射來(lái)獲取相應(yīng)的程序集的相關(guān)類(lèi)型,然后執(zhí)行這些指定類(lèi)型的相關(guān)操作。它是一種即插即用的方案,更新及維護(hù)簡(jiǎn)便。


本文僅僅是描述插件開(kāi)發(fā)的大體模型,設(shè)計(jì)比較簡(jiǎn)單,主要的步驟如下:


(1)、定義公共的接口以及抽象類(lèi)。


(2)、定義和實(shí)現(xiàn)相關(guān)組件。


(3)、實(shí)現(xiàn)通用程序集反射操作類(lèi)。


 


其中,公共的接口和抽象類(lèi)定義在組件Jasen.Framework.Core中,該組件中提供通用程序集反射操作類(lèi)AssemblyUtility;具體實(shí)現(xiàn)的相關(guān)組件為Jasen.Framework.Oracle、Jasen.Framework.Access和Jasen.Framework.SqlServer,它們都實(shí)現(xiàn)了Jasen.Framework.Core中的公共接口。客戶(hù)端可以根據(jù)實(shí)際情況來(lái)進(jìn)行相應(yīng)的操作。相關(guān)組件圖如下:



 


二、公共接口和抽象類(lèi)的定義以及相關(guān)組件的定義和實(shí)現(xiàn)


首先,定義公共的接口以及抽象類(lèi),如下類(lèi)圖所示,定義一個(gè)公共的接口IDataTable,定義一個(gè)抽象類(lèi)DataTable,這些公共的類(lèi)型放置在最頂端的程序集中。而其他組件將分別重新創(chuàng)建,實(shí)現(xiàn)相對(duì)應(yīng)的功能,如SqlServerDataTable、OracleDataTable和AccessDataTable實(shí)現(xiàn)各自的功能。注意:Assembly.LoadFile(file)動(dòng)態(tài)加載程序集時(shí),該程序集在當(dāng)前的運(yùn)行環(huán)境中必須不存在的,否則可能會(huì)出現(xiàn)意想不到的數(shù)據(jù)異常,因此相關(guān)組件的實(shí)現(xiàn)必須是獨(dú)立的(僅僅是實(shí)現(xiàn)公共的接口)。


 


 


三、通用程序集反射操作類(lèi)的實(shí)現(xiàn)


下面的AssemblyUtility主要是對(duì)程序集操作的通用類(lèi),可以根據(jù)指定目錄以及文件列表動(dòng)態(tài)獲取相應(yīng)的程序集。同時(shí),也可以通過(guò)目錄,文件以及程序集獲取相關(guān)的類(lèi)型集合和對(duì)象集合。其中需要注意的是,實(shí)現(xiàn)的子類(lèi)必須提供默認(rèn)構(gòu)造函數(shù)??蛻?hù)端可以通過(guò)該類(lèi)獲取相應(yīng)的類(lèi)型和對(duì)象集合,然后再執(zhí)行相應(yīng)的操作。這些操作都是通過(guò)動(dòng)態(tài)加載程序集來(lái)實(shí)現(xiàn)的,代碼如下所示:


復(fù)制代碼

    public static class AssemblyUtility
    {
        
public static IEnumerable<Type> GetImplementdTypesByDirectory<T>(string baseDirectory)
        {
           IList
<Assembly> assemblies= GetAssemblies(baseDirectory);
           List
<Type> types = new List<Type>();
           
foreach (Assembly assembly in assemblies)
           {
               types.AddRange(GetImplementdTypes
<T>(assembly));
           }

           
return types;
        }

        
public static IEnumerable<Type> GetImplementdTypes<T>(string assemblyFile)
        {
            
if (!File.Exists(assemblyFile))
            {
                
return null;
            }
            
try
            {
                
return GetImplementdTypes<T>(Assembly.LoadFile(assemblyFile));
            }
            
catch (Exception ex)
            {
                
return null;
            }
        }

        
public static IEnumerable<Type> GetImplementdTypes<T>(Assembly assembly)
        {
            
if (assembly == null)
            {
                
return null;
            }

            
return assembly.GetExportedTypes().Where(p =>
               p.IsSubclassOf(
typeof(T)) && (!p.IsAbstract) && (!p.IsInterface));
        }

        
public static IList<T> GetImplementedObjectsByDirectory<T>(string baseDirectory)
        {
            IList
<Assembly> assemblies = GetAssemblies(baseDirectory);
            List
<T> entities = new List<T>();
            
foreach (Assembly assembly in assemblies)
            {
                entities.AddRange(GetImplementedObjects
<T>(assembly));
            }

            
return entities;
        }

        
public static IList<T> GetImplementedObjects<T>(string assemblyFile)
        {
            
if (!File.Exists(assemblyFile))
            {
                
return null;             
            }
            
try
            {
                
return GetImplementedObjects<T>(Assembly.LoadFile(assemblyFile));
            }
            
catch (Exception ex)
            {
                
return null;
            }
        }

        
public static IList<T> GetImplementedObjects<T>(Assembly assembly)
        {
            
if (assembly == null)
            {
                
return null;
            }

            IEnumerable
<Type> types = GetImplementdTypes<T>(assembly);
            var result 
= new List<T>();

            
foreach (Type type in types)
            {
                ConstructorInfo constructor 
= type.GetConstructor(new Type[0]);
                
if (constructor == null)
                {
                    
continue;
                }

                
object instance = Activator.CreateInstance(type);
                
if (instance is T)
                {
                    result.Add((T)instance);
                }
            }

            
return result;
        }

        
public static IList<Assembly> GetAssemblies(string baseDirectory)
        {
            
if (!Directory.Exists(baseDirectory))
            {
                
return new List<Assembly>();
            }

            
string[] files = Directory.GetFiles(baseDirectory, "*.dll");

            
return GetAssemblies(files);
        }

        
public static IList<Assembly> GetAssemblies(string[] assemblyFiles)
        {
            IList
<Assembly> assemblies = new List<Assembly>();
            
try
            {
                
foreach (string file in assemblyFiles)
                {
                    
if (!File.Exists(file)||(!file.EndsWith(".dll",StringComparison.InvariantCultureIgnoreCase)))
                    {
                        
continue;
                    }
                    assemblies.Add(Assembly.LoadFile(file));
                }
            }
            
catch (Exception ex)
            {
                
return new List<Assembly>();
            }

            
return assemblies;
        }
    }
復(fù)制代碼

 


public static IEnumerable<Type> GetImplementdTypesByDirectory<T>(string baseDirectory)
public static IEnumerable<Type> GetImplementdTypes<T>(string assemblyFile)
public static IList<T> GetImplementedObjects<T>(Assembly assembly)


以上3個(gè)方法根據(jù)不同的參數(shù)(目錄、地址、程序集)來(lái)動(dòng)態(tài)獲取程序集中的特定類(lèi)型集合,這些類(lèi)型為類(lèi)型T的類(lèi)或者子類(lèi)(非抽象類(lèi)和接口)。


 


public static IList<T> GetImplementedObjectsByDirectory<T>(string baseDirectory)
public static IList<T> GetImplementedObjects<T>(string assemblyFile)
public static IList<T> GetImplementedObjects<T>(Assembly assembly)
而以上3個(gè)方法根據(jù)不同的參數(shù)(目錄、地址、程序集)來(lái)動(dòng)態(tài)獲取程序集中的特定對(duì)象集合,這些對(duì)象為類(lèi)型T的類(lèi)或者子類(lèi)(非抽象類(lèi)和接口)的實(shí)例。當(dāng)組件中子類(lèi)存在有參構(gòu)造函數(shù)時(shí),必須實(shí)現(xiàn)默認(rèn)構(gòu)造函數(shù)。從如下代碼可以看出:如果默認(rèn)構(gòu)造函數(shù)不存在,將不會(huì)添加該對(duì)象實(shí)例。


                ConstructorInfo constructor = type.GetConstructor(new Type[0]);
                
if (constructor == null)
                {
                    
continue;
                }

                
object instance = Activator.CreateInstance(type);
                
if (instance is T)
                {
                    result.Add((T)instance);
                }


四、通用程序集反射操作類(lèi)的單元測(cè)試


AssemblyUtility類(lèi)主要的單元測(cè)試如下,僅驗(yàn)證了正確的情況,代碼如下:


復(fù)制代碼

    public class AssemblyUtilityTest
    {
        [TestMethod()]
        
public void GetAssembliesTest()
        {
            
string assemblyPath = AppDomain.CurrentDomain.BaseDirectory+"\\Files\\";
            IList
<Assembly> result = AssemblyUtility.GetAssemblies(assemblyPath);

            Assert.IsNotNull(result);
            Assert.AreEqual(
3, result.Count);
        }

        [TestMethod()]
        
public void GetAssembliesByFilesTest()
        {
            
string[] assemblyFiles = new string[] { AppDomain.CurrentDomain.BaseDirectory + "\\Jasen.Framework.Core.dll",
                      AppDomain.CurrentDomain.BaseDirectory 
+ "\\Jasen.Framework.Core.Test.dll",
                      
"www",
                      
"ww.dll"};
            IList
<Assembly> result = AssemblyUtility.GetAssemblies(assemblyFiles);

            Assert.IsNotNull(result);
            Assert.AreEqual(
2, result.Count);
        }

        [TestMethod()]
        
public void GetImplementedObjectsByDirectoryTest()
        {
            
string assemblyDir = AppDomain.CurrentDomain.BaseDirectory + "\\Files\\";
            IList
<DataTable> result = AssemblyUtility.GetImplementedObjectsByDirectory<DataTable>(assemblyDir);
            Assert.IsNotNull(result);
            Assert.AreEqual(
3, result.Count);
        }

        [TestMethod()]
        
public void GetImplementedObjectsTest()
        {
            
string assemblyFile =AppDomain.CurrentDomain.BaseDirectory + "\\Files\\Jasen.Framework.Oracle.dll";   
            IList
<DataTable> result = AssemblyUtility.GetImplementedObjects<DataTable>(assemblyFile);
            Assert.IsNotNull(result);
            Assert.AreEqual(
1, result.Count);
        }

        [TestMethod()]
        
public void GetImplementedTypesTest()
        {
            
string assemblyFile = AppDomain.CurrentDomain.BaseDirectory + "\\Files\\Jasen.Framework.Oracle.dll";
            IEnumerable
<Type> types = AssemblyUtility.GetImplementdTypes<DataTable>(assemblyFile);
            Assert.IsNotNull(types);
            
int count = 0;
            
foreach (var type in types)
            {
                Assert.IsTrue(type.IsSubclassOf(
typeof(DataTable)));
                Assert.IsFalse(type.IsAbstract);
                Assert.IsFalse(type.IsInterface);
                count
++;
            }
            Assert.AreEqual(
1, count);
        }

        [TestMethod()]
        
public void GetImplementdTypesByDirectoryTest() 
        {
            
string assemblyDir = AppDomain.CurrentDomain.BaseDirectory + "\\Files\\";
            IEnumerable
<Type> types = AssemblyUtility.GetImplementdTypesByDirectory<DataTable>(assemblyDir);
            Assert.IsNotNull(types);
            
int count = 0;
            
foreach (var type in types)
            {
                Assert.IsTrue(type.IsSubclassOf(
typeof(DataTable)));
                Assert.IsFalse(type.IsAbstract);
                Assert.IsFalse(type.IsInterface);
                count
++;
            }
            Assert.AreEqual(
3, count);
        }
    }
復(fù)制代碼

 


五、總結(jié)


全文中主要圍繞AssemblyUtility通用類(lèi)來(lái)進(jìn)行講解的,僅僅是插件開(kāi)發(fā)的一個(gè)思路。具體應(yīng)用的話,應(yīng)該相對(duì)來(lái)說(shuō)比較直接,在客戶(hù)端獲取相應(yīng)的類(lèi)型集合以及對(duì)象集合,然后再執(zhí)行這些集合的具體操作即可。其中,實(shí)現(xiàn)的組件(插件)放置在指定的目錄下,通過(guò)AssemblyUtility類(lèi)即可動(dòng)態(tài)加載目錄下的程序集,從而獲取到指定類(lèi)型的數(shù)據(jù)。具體執(zhí)行什么操作,實(shí)現(xiàn)什么功能,這些都是在組件(插件)中實(shí)現(xiàn)即可。


 


源代碼下載:C#插件開(kāi)發(fā)模型源代碼

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多