2017-01-11 13 views
1

У меня есть интерфейс для использования на заводе TypedFactoryFacility от Castle, который берет строку.Замок не разрешает зависимость sub от TypedFactory

public interface IFoo<T> {} 
public interface IBar1 : IFoo<IBar1> {} 
public interface IBar2 : IFoo<IBar2> {} 

public class MyClass1 : IBar1 {} 
public class MyClass2 : IBar2 {} 

public interface IFactory<T> where T : IFoo<T> 
{ 
    T Create(string primitive2); 
} 

Оба MyClasses имеет суб-зависимость:

public class SubDependency : ISubDependency 
{ 
    public SubDependency(string primitive1, string primitive2) 
} 

Я хочу, чтобы установить все MyClasses в заданном пространстве имен на основе IFoo <> но я хочу, чтобы экземпляры запросила и разрешаться интерфейсами IBar , Таким образом, оба интерфейса должны быть зарегистрированы и разрешены к одному и тому же экземпляру того же класса.

Вот мой код установщика:

// register foo 
container.Register(
    Classes.FromAssemblyContaining(typeof(IFoo<>)) 
     .InSameNamespaceAs(typeof(IFoo<>)) 
     .WithServiceAllInterfaces() 
     .LifeStyleHybridPerWebRequestTransient()); 

// register factory 
container.Register(
    Component.For(typeof(IFactory<>)).AsFactory() 
     .LifeStyle.HybridPerWebRequestTransient()); 

// register sub dependency 
container.Register(
    Component.For<ISubDependency>().ImplementedBy<SubDependency>() 
     .LifeStyle.HybridPerWebRequestTransient() 
     .DependsOn(new 
     { 
      primitive1 = "this resolves" 
     })); 

Затем я зарегистрировал свой контейнер, как это:

var container = new WindsorContainer().Install(FromAssembly.This()); 
container.AddFacility<TypedFactoryFacility>(); 

var factory = container.Resolve<IFactory<IBar1>>(); 
var myClass1 = factory.Create("primitive2: this does not resolve"); 

Когда я смотрю на контейнере это показывает, что он зарегистрировал все (хотя я не уверен, что он зарегистрирован правильно).

я получаю следующее сообщение об ошибке:

Could not resolve non-optional dependency for 'SubDependency' (SubDependency). Parameter 'primitive2' type 'System.String'

Я думал, контейнер должен был передать параметр с завода всех зависимостей подразделов, которые имеют аргументы с тем же именем. Как я могу это правильно решить, где я могу определить одно значение в установщике и предоставить другое во время выполнения?

UPDATE: Хотя мой ответ ниже работ я получаю некоторые предупреждения контейнеровозов я не знаю, как решить:

 
All components are potentially misconfigured (except for the IFactory): scope 
Components with potential duplicated dependencies: SubDependency, TypedFactoryComponentSelector 

ответ

0

Я получил его на работу, хотя это кажется ужасным хака, так было бы здорово получить некоторые рекомендации.

Я изменил свою IFoo <> регистрации:

container.Register(
    Classes.FromAssemblyContaining(typeof(IFoo<>)) 
     .InSameNamespaceAs(typeof(IFoo<>)) 
     .WithServiceAllInterfaces() 
     .LifeStyleHybridPerWebRequestTransient() 
     .Configure(r => r.DynamicParameters((k, d) => 
     { 
      var subDependency = k.Resolve<ISubDependency>(d); 
      d.Add("subDepedency", subDependency); 
     }))); 

Это работает, но мне не нравится, и я надеюсь, что есть лучший путь. Это требует, чтобы все классы, которые имеют SubDependency как зависимость называют его «subDependency», например:

public class MyClass1 : IBar1 
{ 
    public MyClass1(SubDependency subDependency) // <-- MUST be named that. 
} 

Я не уверен, если я вызвал больше проблем, то решить с этим решением. Есть ли более простой способ сделать так, чтобы параметр TypedFactory распространялся на все подзависимости, у которых есть аргумент с этим именем?

+0

Несмотря на то, что этот ответ работает, я решил пойти другим путем и, вероятно, в конечном итоге создаст новый вопрос. –