免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
C#插件開發(fā)簡單模型
一、前言 

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


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


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


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


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


 


其中,公共的接口和抽象類定義在組件Jasen.Framework.Core中,該組件中提供通用程序集反射操作類AssemblyUtility;具體實現(xiàn)的相關(guān)組件為Jasen.Framework.Oracle、Jasen.Framework.Access和Jasen.Framework.SqlServer,它們都實現(xiàn)了Jasen.Framework.Core中的公共接口??蛻舳丝梢愿鶕?jù)實際情況來進行相應(yīng)的操作。相關(guān)組件圖如下:



 


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


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


 


 


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


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



    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;
        }
    }

 


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個方法根據(jù)不同的參數(shù)(目錄、地址、程序集)來動態(tài)獲取程序集中的特定類型集合,這些類型為類型T的類或者子類(非抽象類和接口)。


 


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個方法根據(jù)不同的參數(shù)(目錄、地址、程序集)來動態(tài)獲取程序集中的特定對象集合,這些對象為類型T的類或者子類(非抽象類和接口)的實例。當組件中子類存在有參構(gòu)造函數(shù)時,必須實現(xiàn)默認構(gòu)造函數(shù)。從如下代碼可以看出:如果默認構(gòu)造函數(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);
                }


四、通用程序集反射操作類的單元測試


AssemblyUtility類主要的單元測試如下,僅驗證了正確的情況,代碼如下:



    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);
        }
    }

 


五、總結(jié)


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


 


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

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
當類庫項目中無法使用Application.StartupPath的時侯 (注:主要是在進行反射讀取文件的時候!!)
C# 修改配置文件進行窗體logo切換
C# LINQ詳解(一)
java泛型總結(jié)
List之Union(),Intersect(),Except() 亦可以說是數(shù)學中的并集,交集,差集
值類型和引用類型 - Omiga - 博客園
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服