2009-09-04 6 views
3

Comment remplir TODO pour que ce test réussisse?Unity Container: utiliser ContainerControlledLifetimeManager par défaut pour le groupe de méthodes "Resolve"

class MyClass { } 

[Test] 
public void Singleton_by_default_test() 
{ 
    var parentContainer = GetUnityContainer();   
    var container = parentContainer.GetChildContainer(); 

    // TODO: Add magic here (but do NOT explicitly register MyClass in container!) 

    Assert.AreSame(container.Resolve<MyClass>(), container.Resolve<MyClass>()); 
} 

Mise à jour: Il y a une manière qui utilise l'héritage.

public class SingletonContainer : UnityContainer 
{ 
    public override object Resolve(Type t, string name) 
    { 
     var obj = base.Resolve(t, name); 
     RegisterInstance(t, name, obj, new ContainerControlledLifetimeManager()); 
     return obj; 
    } 
} 

J'utilise container.GetChildContainer() pour obtenir instance de récipient de sorte que cette méthode ne me pas suite.

Répondre

4

Je vois où vous voulez en venir. Problème intéressant

Je pense que vous pouvez faire ce que vous faites avec une extension Unity Behavior. Voici un excellent article sur la conception de Unity qui décrit le travail de certains éléments d'Unity que beaucoup de gens ne connaissent pas: http://msdn.microsoft.com/en-us/library/dd140062.aspx

Le conteneur Unity utilise essentiellement une «chaîne de stratégie» lors du traitement d'une demande de résolution . L'une des stratégies de la chaîne est la LifetimeStrategy. La meilleure chose à faire serait de créer une nouvelle stratégie et de l'insérer dans la chaîne avant le LifetimeStrategy de sorte que lorsque votre stratégie a une chance de regarder le type, elle peut enregistrer un ContainerControlledLifetimeManager pour ce type dans le courant récipient. Il arrivera à LifetimeStrategy et il y aura déjà un ContainerControlledLifetimeManager enregistré pour ce type.

Il pourrait ressembler à ceci:

public class MakeEverythingSingletonStrategy : BuilderStrategy 
{ 
    public override void PreBuildUp(IBuilderContext context) 
    { 
      Type objectType = BuildKey.GetType(context.BuildKey); 
      context.PersistentPolicies.Set<ILifetimePolicy>(
        new SingletonLifetimePolicy(), 
        context.BuildKey); 

    } 
} 

Vous devriez être en mesure d'appliquer cette configuration au conteneur sous en utilisant la méthode Configure<T>, en passant dans une classe de configuration qui ajoute cette nouvelle extension.

J'ai trouvé un bon échantillon de quelqu'un sur Stackoverflow mettre en œuvre une coutume BuilderStrategy:

Custom object factory extension for Unity

0

Essayez de l'utiliser comme singleton. Vous pouvez utiliser le conffiguration suivant pour votre MyClass: *

<type type="MyClass" mapTo="MyClass"> 
    <lifetime type="singleton" /> 
</type> 
+0

Vous enregistrez le type explicitement. Je ne veux pas savoir à l'avance tous les types dont j'ai besoin. –

Questions connexes