簡體   English   中英

TinyIoC解決插件合同

[英]TinyIoC Resolve Plugin Contract

如何使用TinyIoC解決插件聯系人?

Host.exe / w對Core.Contract.dll的引用

var container = new TinyIoCContainer();
container.AutoRegister(new[] { Assembly.LoadFrom("Core.Contracts.dll") }, 
                DuplicateImplementationActions.RegisterMultiple);
container.AutoRegister(new[] { Assembly.LoadFrom("EchoCodeAnalysis.dll") }, 
                DuplicateImplementationActions.RegisterMultiple);
var mi = container.Resolve<IService>();

合同IService位於Core.Contracts.dll中,並且是宿主程序集中的參考,這是給拖放插件提供無需重新編譯即可工作的機會。 在EchoCodeAnalysis.dll中,我們具有實際的插件實現,該插件實現在主機程序集中未引用,但使用IService共享Core.Contracts.dll的主機。

Core.Contract.dll:

public interface IService
{
    string ID { get; set; }
}

EchoCodeAnalysis.dll:

public class Service : IService
{
    string IService.ID
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
}

編輯:

我設法解決了問題的第一部分。

var type = typeof(IService);
var types = (new[] { Assembly.LoadFrom("EchoCodeAnalysis.dll") }).ToList()
                .SelectMany(s => s.GetTypes())
                .Where(x => type.IsAssignableFrom(x) && x.IsClass).ToList();

container.RegisterMultiple<IService>(types.ToArray());

var mi = container.ResolveAll<Core.Contracts.IService>();

將獲取並解析所有IService接口,從而將插件限制為該接口,而不是任何高級實現。 假設將IMenuItem嵌入為IService,上面的代碼可以找到任何可追溯到IService起源的類,但是那些明確實現IMenuItem且具有可以說名字的類,當解析為IService時,它將僅獲取IService屬性並且不包含IMenuItem屬性。 那是那里。 container.Register(types.ToArray())。AsRespectiveImplementations()將派上用場。 但是這個問題周圍有什么地方嗎? 還是必須編寫此實用程序才能擴展TinyIOC?

編輯2:

然后,我們移至擴展程序,但仍未解決任何問題。

    public static IEnumerable<T> GetPluginsForModule<T>()
    {
        var type = typeof(T);
        var types = Plugins.SelectMany(s => s.GetTypes())
            .Where(x => type.IsAssignableFrom(x) && x.IsClass).ToList();
        foreach (var t in types)
        {
            if (t.CustomAttributes.Where(x => x.AttributeType == typeof(CluraPlugin)).Any()) 
            {
                CustomAttributeData attr = t.CustomAttributes.Where(x => x.AttributeType == typeof(CluraPlugin)).FirstOrDefault();
                if (attr == null)
                    break;

                string Name = attr.ConstructorArguments.Where(x => x.ArgumentType == typeof(string)).FirstOrDefault().Value as string;
                Type InterfaceTypeArgument = attr.ConstructorArguments.Where(x => x.ArgumentType == typeof(Type)).FirstOrDefault().Value as Type;

                Container.Register(InterfaceTypeArgument, t, Name).AsMultiInstance();
            }
        }
        return Container.ResolveAll(type) as IEnumerable<T>;
    }

我傳遞了正確的值,在上面的Container.Register中,我們有InterfaceTypeArgument = IMenuItem,t = EchoMenu:IMenuItem,Name =“ EchoMenu”,但是當我們要求容器在將EchoMenu作為其實現注冊后解析IMenuItem時,將返回null從解決所有。

有什么想法嗎?

我通過基准測試找到了一種方法,不確定最佳實踐或將來的潛在內存問題。

使用:

string PluginDirectory = Directory.GetCurrentDirectory() +"\\Plugins\\";
PluginManager.LoadDirectory(PluginDirectory);
var mi = PluginManager.GetPluginsForModule<IService>();

可以解決以下問題:

public static IEnumerable<object> GetPluginsForModule<T>()
{
    var type = typeof(T);
    var types = Plugins.SelectMany(s => s.GetTypes())
            .Where(x => type.IsAssignableFrom(x) && x.IsClass).ToList();
    foreach (var t in types)
    {
        if (t.CustomAttributes.Where(x => x.AttributeType == typeof(CluraPlugin)).Any()) 
        {
           CustomAttributeData attr = t.CustomAttributes.Where(x => x.AttributeType == typeof(CluraPlugin)).FirstOrDefault();
           if (attr == null)
              break;

           string Name = attr.ConstructorArguments.Where(x => x.ArgumentType == typeof(string)).FirstOrDefault().Value as string;
           Type InterfaceTypeArgument = attr.ConstructorArguments.Where(x => x.ArgumentType == typeof(Type)).FirstOrDefault().Value as Type;

           Container.Register(InterfaceTypeArgument, t, Name).AsMultiInstance();
         }
     }
     return Container.ResolveAll(type);
}

動態運行時可能不是最佳選擇,因此一旦啟動應用程序並從插件類型列表中使用它們,可能需要插件管理器將實現作為實例保存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM