如何使用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时,我们可以从resolve中获得null。
有什么想法吗?
发布于 2015-05-23 21:13:03
我找到了一种方法,不确定未来的最佳实践或潜在的内存问题,通过基准测试。
使用:
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);
}在执行任务时,这可能不是最优的,因此可能需要插件管理器在启动应用程序并从插件类型列表中使用它们时,将实现作为实例保存。
https://stackoverflow.com/questions/30408663
复制相似问题