Unity IoC для динамического разрешения сборок - PullRequest
2 голосов
/ 07 марта 2012

Мы используем единство как IoC. Мы столкнулись с уникальной проблемой. Мы создали интерфейс под названием IPlugin. Этот интерфейс используется разными сторонними поставщиками для разработки своих собственных плагинов на основе этого интерфейса. Эти плагины затем вписываются в нашу систему. Продавцы предоставят свои заглушки как dll. Что мы хотим, Используя Unity, мы хотим разрешить все типы сборок, которые реализованы с помощью интерфейса IPlugin. Я узнал, что это достижимо с помощью атрибута экспорта MEF, мне интересно, может ли это быть достигнуто с помощью Unity, используя некоторое расширение.

Наш код

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
*/
}

Сборка поставщика

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

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

}

Ответы [ 2 ]

5 голосов
/ 07 марта 2012

Вы можете написать немного кода Reflection, который просматривает папку для сборок надстроек и регистрирует все реализации IPlugin с контейнером.

Что-то подобное должно работать:

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);

(код может не скомпилироваться)

3 голосов
/ 11 мая 2015
    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());
    });

Если кого-то все еще волнует, это то, что я сделал, чтобы динамически загружать библиотеки DLL, в которых реализован определенный интерфейс (ICommonWorker).

...