Search code examples
c#.netwinformsdll.net-assembly

Specifying an Assembly to Create an Object


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?


Solution

  • Thanks to @MarcGravell found a solution to this problem. Refer these links to the original post.

    Link 01

    Link 02

    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.