I have a C# application. It has a referenced class library Generic.dll
.
I have a Document
class inside Generic.dll
.
namespace Generic
{
public class Document
{
public virtual string ObjectName()
{
return "Generic";
}
}
}
Then I created another class library Custom.dll
and created a Document
by inheriting the Document
class in Generic.dll
namespace Custom
{
public class Document : Generic.Document
{
public override string ObjectName()
{
return "Custom";
}
}
}
In my application I'm creating a Document
object.
Document document = new Document();
Console.WriteLine(document.ObjectName());
Console.ReadLine();
When my application running if there is any way to tell the runtime if Custom.dll
is available make Document
object from Custom.dll
or use Generic.dll
?
NOTE: Custom.dll
is not referenced to the application
EDIT:
I used the following method to create the object based on the Custom.dll
availability. This will return Generic.Document
object if either Custom.dll
is not found nor couldn't load or will return Custom.Document
if Custom.dll
available.
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));
}
}
I used the above method to like this;
//Custom class
Document custDocument = Utility.CreateObject<Document>();
Console.WriteLine(custDocument.ObjectName());
Console.ReadLine();
this will return the desired Document
object. But can't we instruct the Runtime to get assembly when creating object uisng new
keyword?
Thanks to @MarcGravell found a solution to this problem. Refer these links to the original post.
The code as below;
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";
}
}
Now when I initialize Document
object;
Document document = new Document();
This actually calls the CreateInstance
method of the GenericProxyAttribute
class. There I load the Custom.dll
and initiate a Document
object. Then return the Custom.Document
object. When the Custom.dll
is not available returns the Generic.Document
.