Unity IoC for resolving assemblies dynamically

2019-02-07 14:23发布

问题:

We are using unity as IoC. We came across unique problem. We have created interface called IPlugin. This interface is shared across various third party vendors to develop their own plug in based on this interface. These plug ins then fits into our system. Vendors will provide their plugs in as dll. What we want is , Using unity we want to resolve all assembly’s type which is implemented with IPlugin interface. I came to know that this is achievable via MEF export attribute, I am wondering whether this can be achieved via Unity using some short of extension.

Our code

Public interface IPlugin
{
    Void ProcessData();
} 

Public class DataProcessor
{
    Var pluginList = unityContainer.ResolveAssemblies<IPlugIn>()
/*
There is no such method in unity but what we want is scan all assemblies in bin folder and load all types which are inheriting from IPlugIn
*/
}

Vendor’s assembly

Public class AbcCompanyPlugIn : IPlugin
{
Void ProcessData()
{
// some code
}

}
Public class XyzCompanyPlugIn : IPlugin
{
Void ProcessData()
{
// some code
}

}

回答1:

You could write a bit of Reflection code that scans a folder for add-in assemblies and registers all IPlugin implementations with the container.

Something like this ought to work:

var assemblies = // read all assemblies from disk
var pluginTypes = from a in assemblies
                  from t in a.GetExportedTypes()
                  where typeof(IPlugin).IsAssignableFrom(t)
                  select t;

foreach (var t in pluginTypes)
    container.RegisterType(typeof(IPlugin), t);

(code may not compile)



回答2:

    var assemblies = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "Worker*.dll").Select(f => Assembly.LoadFile(f)).ToArray<Assembly>();

    (from asm in assemblies
        from t in asm.GetExportedTypes()
        where typeof(ICommonWorker).IsAssignableFrom(t) && t.IsClass
        select t).ForEach(x =>
    {
        unityContainer.RegisterType(typeof(ICommonWorker), x, x.FullName, new ContainerControlledLifetimeManager());
    });

If anyone still cares, this is what I did to load DLL's dynamically which implemented a specific interface (ICommonWorker).