Как можно разрешить контакты плагина с помощью 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 у нас есть фактическая реализация плагина, которая не упоминается в сборке хоста, но совместно использует хост Core.Contracts.dll с помощью IService.
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", но когда мы просим контейнер разрешить IMenuItem после регистрации EchoMenu в качестве его реализации, мы получаем нуль обратно от разрешить все.
есть идеи?
IService
, и вы хотите разрешить конкретную одну или все из них? - person NeddySpaghetti   schedule 23.05.2015container.AutoRegister()
, то есть без каких-либо параметров? - person NeddySpaghetti   schedule 23.05.2015