指定程序集以创建对象

Specifying an Assembly to Create an Object

我有一个 C# 应用程序。它有一个引用 class 库 Generic.dll。 我在 Generic.dll.

里面有一个 Document class
namespace Generic
{
    public class Document
    {
        public virtual string ObjectName()
        {
            return "Generic";
        }
    }
}

然后我创建了另一个class库Custom.dll并通过继承Generic.dll[=35中的Documentclass创建了一个Document =]

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 可用性创建对象。如果 Custom.dll 未找到或无法加载,这将 return Generic.Document 对象,如果 Custom.dll 可用,将 return Custom.Document 对象。

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

这将 return 所需的 Document 对象。但是我们不能在创建对象时指示运行时获取程序集 uisng new 关键字吗?

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

这确实需要应用程序 配置 到 select 一个实现或另一个 - 如果自定义实现可用,您希望您的应用程序以不同的方式运行。

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

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

object instance = Activator.CreateInstance(type);

(请注意,您可以通过提供 Version=Culture= 来更具体,并且已签名的程序集必须包含要指定的 PublicKeyToken=

没有找到接口的所有实现的内置方法 - 除了必须加载和检查所有符合条件的程序集和安全威胁之外,通常不希望应用程序根据存在的存在而表现不同一个文件。

感谢@MarcGravell 找到了这个问题的解决方案。 请将这些链接指向原始链接 post。

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

这实际上调用了GenericProxyAttributeclass的CreateInstance方法。我在那里加载 Custom.dll 并启动一个 Document 对象。然后 return Custom.Document 对象。当 Custom.dll 不可用时 returns Generic.Document.