CustomTraceListner using Assembly.LoadFrom

Topics: Exception Handling Application Block, Logging Application Block
Mar 27, 2013 at 7:31 PM
I have created a custom trace listener that inherits from the Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.CustomTraceListener.
The trace listener is a utility dll and the utility dll is reading its config file from utility.dll.config.
So I am using LogWriterFactory("utility.dll.config") to create the LogWriter.
When I add a direct reference in a console application to my utility.dll then every thing works fine.
But if I use Assembly.LoadFrom("utility.dll") then I get the following error:
"The type 'Utility.CustomTraceListner, Utility' cannot be resolved."
If I add utility.dll to the GAC then every thing works fine.
I can run AppDomain.CurrentDomain.GetAssemblies() on the line right above the logWriterFactory.Create() and see that utility.dll has been loaded.
I can even run AppDomain.CurrentDomain.CreateInstanceFrom("Utility.dll", "Utility.CustomTraceListener") right before calling logWriterFactory.Create() and get an instance without any problems.
It's almost like the Ent Library is using its own app domain.
Mar 27, 2013 at 8:14 PM
Edited Mar 27, 2013 at 8:15 PM
In most scenarios you shouldn't have to manually load any assemblies. The assembly will be resolved automatically by the .NET runtime using the standard load logic.

You do need to ensure that the Utility.dll is resolvable at runtime. If the assembly is in the GAC then it will be resolvable and if you add a reference then Visual Studio will (usually) copy the assembly over to the output directory so the assembly will be resolved. In other cases you need to ensure the assembly is resolvable. One way to do this is using a post build command to copy the assembly to the appropriate directory.

If this isn't the issue, then can you provide more details (e.g. code, configuration etc.) to help reproduce the issue?

Randy Levy
Enterprise Library support engineer
Support How-to
Mar 27, 2013 at 8:40 PM
Thanks for the reply.
I guess I should have added some more information.
So here goes a better explanation.
We have an application that uses Assembly.LoadFrom to load external dlls.
Each dll needs its own config file / logging settings.
We do not have control of the application nor can we add dlls into the applications bin folder.
Also adding the external dlls into the GAC is not an option.
Something in the Ent Library is not able to resolve the utility.dll even thought the code calling the Ent Library is able to resolve the utility.dll just fine.
The utility.dll is in the AppDomain.CurrentDomain.GetAssemblies() so I don't understand why Ent Library can't seem to resolve the information.
We are hoping that the application does not need to know about the Ent Library or even that the utility.dll is using the Ent Library for logging.
Mar 27, 2013 at 9:25 PM
You could look at handling the AssemblyResolve event similar to this post.

Here's a simple example:
public class Class1
    static Class1()
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Custom_Resolve);

    public Class1()

    private static Assembly Custom_Resolve(object sender, ResolveEventArgs args)
        var assemblyInfo = args.Name.Split(',');
        string assemblyName = assemblyInfo[0] + ".dll";

        if (assemblyName == "Utility.dll")
            return Assembly.LoadFile(@"C:\Utility\bin\Debug\Utility.dll");

        return null;

    public void Do()
        var configSource = new FileConfigurationSource(@"C:\Utility\bin\Debug\Utility.dll.config");
        LogWriterFactory factory = new LogWriterFactory(configSource);

        var logger = factory.Create();
        logger.Write("Test", "General");
This seems to work in a scenario similar to yours where I use reflection to load and call MyClass:
var myAssembly = Assembly.LoadFrom(@"C:\MyAssembly\bin\Debug\MyAssembly.dll");
var class1Type = myAssembly.GetType("MyAssembly.Class1");
var class1 = Activator.CreateInstance(class1Type);

class1Type.InvokeMember("Do", BindingFlags.InvokeMethod, null, class1, null);
Randy Levy
Enterprise Library support engineer
Support How-to
Mar 28, 2013 at 12:32 PM
This worked great. Thanks for your help.