2009-08-17 8 views
1

J'utilise la méthode décrite par Bojan Resnik dans this question pour résoudre les instances de classes qui ne sont pas enregistrées dans le conteneur Windsor. Le problème est que je ne veux pas que ces classes soient disponibles en tant que "services" aux autres instances résolues.Castle IoC - Comment puis-je empêcher les composants enregistrés d'être résolus en tant que dépendances?

Par exemple, étant donné les classes suivantes:

class Order 
{ 
    public Order(ITaxCalculator tc) 
    { 
     // ... 
    } 
} 

class SomeOtherThing 
{ 
    public SomeOtherThing(ISomeOtherService sos) 
    { 
     // ... 
    } 

    Order CurrentOrder 
    { 
     get; 
     set; 
    } 
} 

static class WindsorExtensions 
{ 
    public static object Create(this IWindsorContainer container, Type type) 
    { 
     if (!type.IsClass) 
     { 
      throw new ArgumentException("not class", "type"); 
     } 

     if (!container.Kernel.HasComponent(type)) 
     { 
      container.Kernel.AddComponent(type.FullName, type, LifestyleType.Transient); 
     } 

     return container.Resolve(type); 
    } 

    public static T Create<T>(this IWindsorContainer container) 
    { 
     return (T)ResolveType(container, typeof(T)); 
    } 
} 

Je veux pouvoir dire:

Order order = container.Create<Order>(); 
SomeOtherThing thing = container.Create<SomeOtherThing>(); 

Mais je ne veux pas une nouvelle instance de l'ordre pour obtenir injecté dans la propriété CurrentOrder de SomeOtherThing. Fondamentalement, je veux que le conteneur crée l'instance pour que les dépendances puissent être injectées, mais je ne veux pas que les classes puissent être injectées dans d'autres classes.

Cela ne me dérange pas d'avoir à écrire des extensions supplémentaires dans le conteneur afin d'y parvenir si quelqu'un peut me diriger dans la bonne direction.

Répondre

0

Par défaut, windsor utilise l'injection du constructeur plutôt que l'injection de propriété. À cause de cela, CurrentOrder ne sera jamais injecté dans la classe SomeOtherThing à moins que vous ne l'ajoutiez au constructeur.

En regardant votre code, vous êtes essentiellement en retard d'enregistrement du composant dans le conteneur. Si vous voulez être sûr qu'il n'a jamais été injecté, vous pouvez l'enlever une fois qu'il a résolu par exemple.

static class WindsorExtensions 
{ 
public static object Create(this IWindsorContainer container, Type type) 
{ 
    if (!type.IsClass) 
    { 
     throw new ArgumentException("not class", "type"); 
    } 
    if (!container.Kernel.HasComponent(type)) 
    { 
     container.Kernel.AddComponent(type.FullName, type, LifestyleType.Transient); 
    } 
    object instance = container.Resolve(type); 
    container.Kernel.RemoveComponent(type.FullName); 
    return instance; 

} 

public static T Create<T>(this IWindsorContainer container) 
{ 
    return (T)ResolveType(container, typeof(T)); 
} 
} 
1

Je pense que this workaround va résoudre votre problème car il utilise un noyau de l'enfant pour le composant « non enregistré », donc il ne devrait pas affecter d'autres composants.

Questions connexes