2009-05-12 2 views
5

Alcuni contenitori di iniezione dipendenza consentono di iniettare servizi configurati in un oggetto già costruito.Castello di Windsor Proprietà di iniezione dell'oggetto costruito

Questo può essere ottenuto utilizzando Windsor, tenendo conto delle eventuali dipendenze del servizio che possono esserci sull'oggetto target?

+2

Duplicate: http://stackoverflow.com/questions/447193 –

+0

Non è un duplicato di quella domanda. La domanda cui si fa riferimento chiede se il windsor può risolvere oggetti che non sono registrati. – PhilHoy

risposta

5

No, non è possibile.

1

Come ha detto Krzysztof, non esiste una soluzione ufficiale per questo. Potresti provare a provare this workaround.

Personalmente, considero dover fare un odore di codice. Se è il tuo codice, perché non è registrato nel contenitore? Se non è il tuo codice, scrivi una fabbrica/adattatore/ecc.

+0

Sono d'accordo - è un odore. Perché vuoi farlo in primo luogo? È semplicemente sbagliato. –

+0

Ho un caso piuttosto semplice in cui ho bisogno di fare questo: – Steve

+0

Creo un'istanza tramite il contenitore, quindi a un certo punto serializzo la mia istanza. Tuttavia non voglio serializzare le dipendenze. Quando deserializzo ho bisogno di aggiungere nuovamente le dipendenze nell'oggetto. Come risolverei questo problema usando Castle Windsor? – Steve

9

Questa è una vecchia domanda, ma Google mi ha condotto qui di recente, quindi ho pensato di condividere la mia soluzione per non aiutare qualcuno a cercare qualcosa come il metodo BuildUp di StructureMap per Windsor.

Ho scoperto che potrei aggiungere questa funzionalità da solo relativamente facilmente. Ecco un esempio che inietta solo le dipendenze in un oggetto dove trova una proprietà tipizzata all'interfaccia nullo. Si potrebbe estendere il concetto ulteriormente, naturalmente a cercare un particolare attributo, ecc:

public static void InjectDependencies(this object obj, IWindsorContainer container) 
{ 
    var type = obj.GetType(); 
    var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); 
    foreach (var property in properties) 
    { 
     if (property.PropertyType.IsInterface) 
     { 
      var propertyValue = property.GetValue(obj, null); 
      if (propertyValue == null) 
      { 
       var resolvedDependency = container.Resolve(property.PropertyType); 
       property.SetValue(obj, resolvedDependency, null); 
      } 
     } 
    } 
} 

Ecco un semplice test di unità per questo metodo:

[TestFixture] 
public class WindsorContainerExtensionsTests 
{ 
    [Test] 
    public void InjectDependencies_ShouldPopulateInterfacePropertyOnObject_GivenTheInterfaceIsRegisteredWithTheContainer() 
    { 
     var container = new WindsorContainer(); 
     container.Register(Component.For<IService>().ImplementedBy<ServiceImpl>()); 

     var objectWithDependencies = new SimpleClass(); 
     objectWithDependencies.InjectDependencies(container); 

     Assert.That(objectWithDependencies.Dependency, Is.InstanceOf<ServiceImpl>()); 
    } 

    public class SimpleClass 
    { 
     public IService Dependency { get; protected set; } 
    } 

    public interface IService 
    { 
    } 

    public class ServiceImpl : IService 
    { 
    } 
} 
+2

A proposito, Avevo bisogno di questa funzionalità per inject dependencies in ActionFilter per MVC.NET. –