指定要创建对象的部件

本文关键字:创建对象 | 更新日期: 2023-09-27 17:50:57

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

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

然后我创建了另一个类库Custom.dll,并通过继承Generic.dll 中的Document类创建了一个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或使用Generic.dll生成Document对象?

注:Custom.dll未参考应用

编辑:

我使用以下方法来创建基于Custom.dll可用性的对象。如果未找到或无法加载Custom.dll,这将返回Generic.Document对象;如果Custom.dll可用,则返回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();

这将返回所需的CCD_ 19对象。但是,当使用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对象。当CCD_ 27不可用时,返回CCD_。

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

不过,这确实需要对应用程序进行配置以选择一个实现或另一个实现-如果有自定义实现,您希望应用程序的操作有所不同。

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

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

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

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