我有一个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
关键字时,我们是否无法指示运行时获取程序集?
答案 0 :(得分:1)
感谢@MarcGravell找到了解决这个问题的方法。 请将这些链接引用到原始帖子。
以下代码;
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=
没有内置的方法来查找接口的所有实现 - 除了必须加载和检查所有符合条件的程序集和安全威胁之外,通常不希望具有基于存在的行为不同的应用程序文件。