簡體   English   中英

指定程序集創建對象

[英]Specifying an Assembly to Create an Object

我有一個C#應用程序。 它具有一個引用的類庫Generic.dll 我在Generic.dll有一個Document類。

namespace Generic
{
    public class Document
    {
        public virtual string ObjectName()
        {
            return "Generic";
        }
    }
}

然后,我創建了另一個類庫Custom.dll並創建了一個Document在繼承的DocumentGeneric.dll

namespace Custom
{
    public class Document : Generic.Document
    {
        public override string ObjectName()
        {
            return "Custom";
        }
    }
}

在我的應用程序中,我正在創建一個Document對象。

Document document = new Document();
Console.WriteLine(document.ObjectName());
Console.ReadLine();

當我的應用程序運行時,是否有任何方法可以告訴運行時Custom.dll是否可用,請從Custom.dll獲取Document對象還是使用Generic.dll

注意: Custom.dll未引用到該應用程序

編輯:

我使用以下方法根據Custom.dll可用性創建對象。 這將返回Generic.Document對象如果任Custom.dll沒有找到,也沒有無法加載或將返回Custom.Document如果Custom.dll可用。

public static T CreateObject<T>()
        {
            string zTypeName = typeof(T).Name;

            try
            {
                Assembly zLibrary = Assembly.LoadFrom(@"C:\Somewhere\Custom.dll");
                Type zType = zLibrary.GetType(string.Format("Custom.{0}", zTypeName), false, true);
                object zInstance = Activator.CreateInstance(zType);

                return (T)zInstance;
            }
            catch (Exception ex) 
            {
                Console.WriteLine(ex.Message);
                return (T)Activator.CreateInstance(typeof(T));
            }
        }

我使用上面的方法來喜歡這個;

//Custom class
           Document custDocument = Utility.CreateObject<Document>();
           Console.WriteLine(custDocument.ObjectName());
           Console.ReadLine();

這將返回所需的Document對象。 但是我們不能在創建對象uisng new關鍵字時指示運行時獲取程序集嗎?

感謝@MarcGravell找到了解決此問題的方法。 將這些鏈接引用到原始帖子。

鏈接01

鏈接02

代碼如下;

    public class GenericProxyAttribute : ProxyAttribute
    {
        public override MarshalByRefObject CreateInstance(Type serverType)
        {
            string zTypeName = serverType.Name;

            try
            {
                Assembly zLibrary = Assembly.LoadFrom(@"C:\Assemblies\Custom.dll");
                Type zType = zLibrary.GetType(string.Format("Custom.{0}", zTypeName), false, true);
                return base.CreateInstance(zType);
            }
            catch (Exception)
            {
                return base.CreateInstance(serverType);
            }
        }
    }

    [GenericProxy]
    public class Document : ContextBoundObject
    {
        public virtual string GetObjectName() 
        {
            return "Generic Document"; 
        }
    }

現在,當我初始化Document對象時;

Document document = new Document();

實際上,這將調用GenericProxyAttribute類的CreateInstance方法。 在那里,我加載Custom.dll並啟動一個Document對象。 然后返回Custom.Document對象。 如果Custom.dll不可用,則返回Generic.Document

能夠為接口選擇定制實現是非常普遍的。 正如其他人所提到的,有依賴注入框架,並且有很多關於此主題的信息。

這確實需要將應用程序配置為選擇一個實現或另一個實現-如果希望使用自定義實現,則希望應用程序以不同的方式運行。

您不必選擇提供庫的文件名 ,而可以選擇提供以下類型的AssemblyQualifiedName

Type type = Type.GetType("Namespace.Type, AssemblyName", false);
if (type == null)
{
    type = typeof(T);
}

object instance = Activator.CreateInstance(type);

(請注意,您可以通過提供Version=Culture=來更加具體,並且簽名的程序集必須包含PublicKeyToken=才能指定)

沒有內置的方法可以找到接口的所有實現-除了必須加載和檢查所有符合條件的程序集和安全威脅之外,通常不希望具有基於文件存在而表現不同的應用程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM