指定要创建对象的程序集

时间:2015-05-27 05:28:13

标签: c# .net winforms dll .net-assembly

我有一个C#应用程序。它有一个引用的类库Generic.dll。 我在Document内有一个Generic.dll课程。

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

然后我创建了另一个类库Custom.dll并通过继承Document

中的Document类创建了Generic.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是否可用,请Document使用Custom.dll对象或使用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关键字时,我们是否无法指示运行时获取程序集?

2 个答案:

答案 0 :(得分:1)

感谢@MarcGravell找到了解决这个问题的方法。 请将这些链接引用到原始帖子。

  

Link 01

     

Link 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();

这实际上调用了CreateInstance类的GenericProxyAttribute方法。在那里,我加载Custom.dll并启动Document对象。然后返回Custom.Document对象。如果Custom.dll不可用,则返回Generic.Document

答案 1 :(得分:0)

能够为界面选择自定义实现是很常见的。正如其他人所提到的,有依赖注入框架,并且有很多关于这个主题的信息。

这确实要求应用程序配置以选择一个或另一个实现 - 如果自定义实现可用,您希望应用程序采取不同的行动。

您可以选择提供类型的AssemblyQualifiedName,而不必知道库的文件名

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

object instance = Activator.CreateInstance(type);

(请注意,提供Version=Culture=可以更具体,而签名的程序集必须包含要指定的PublicKeyToken=

没有内置的方法来查找接口的所有实现 - 除了必须加载和检查所有符合条件的程序集和安全威胁之外,通常不希望具有基于存在的行为不同的应用程序文件。