2010-09-23 2 views
0

J'ai un objet "TestProperty" qui implémente "ITestProperty". "TestProperty" prend un argument de constructeur de chaîne. Ceci est configuré dans StructureMap en utilisant quelque chose le long des lignes CtorDependency ou WithCtorArg.Comment StructureMap peut-il être utilisé pour créer des dépendances de setter d'objets ayant des arguments de constructeur primitifs?

Je souhaite injecter l'instance de "ITestProperty" (implémentée avec "TestProperty") dans une autre classe en tant que propriété. Lorsque j'essaie d'exécuter le code, j'obtiens une exception (Code d'erreur StructureMap 205, "Propriété Instance demandée manquante").

est ici une version simplifiée qui recrée le problème:

Test:

[Test] 
public void Can_resolve_the_correct_property() 
{ 
    ObjectFactory.Initialize(x => x.AddRegistry(new TestRegistry())); 

    var instance = ObjectFactory.GetInstance<TestController>(); 
} 

Configuration du Registre:

public class TestRegistry : Registry 
{ 
    public TestRegistry() 
    { 
     ForRequestedType<ITestProperty>().AddInstances( 
      i => i.OfConcreteType<TestProperty>().WithName("Test") 
       .CtorDependency<string>("arg").Is("abc") 
     ); 

     //ForConcreteType<TestProperty>().Configure 
      .CtorDependency<string>("arg").Is("abc"); 

     ForConcreteType<TestController>().Configure 
      .SetterDependency(p => p.Property).Is<TestProperty>() 
      .WithName("Test"); 
    } 
} 

Objets d'essai:

public interface ITestProperty { } 

public class TestProperty : ITestProperty 
{ 
    private readonly string arg; 

    public TestProperty(string arg) 
    { 
     this.arg = arg; 
    } 

    public string Arg { get { return arg; } } 
} 

public class TestController 
{ 
    public ITestProperty Property { get; set; } 
} 

Quand nous allons initia lize l'objet "TestController" au-dessus de l'exception est levé. Est-ce possible avec StructureMap? En supposant que c'est possible, que dois-je faire pour le faire fonctionner?

Merci d'avance.

+1

Vos inscriptions vous montre la création d'un code instance nommée « Test », mais votre test demande que l'instance par défaut (pas de nom spécifié). La dénomination de l'instance est-elle pertinente? –

+0

Oui, c'est une version simplifiée de ce que nous avons en production - nous avons plusieurs instances. Cela dit, je préférerais ne pas utiliser les instances nommées si possible et traiter uniquement les types - il y a d'autres raisons pour lesquelles nous les avons utilisées. –

Répondre

1

Il y a plusieurs façons de le faire, comme Josh mentionné si l'instance nommée est donc important que vous voulez dans votre registre:

ForRequestedType<ITestProperty>().AddInstances(i => 
    i.OfConcreteType<TestProperty>().WithName("Test") 
     .WithCtorArg("arg").EqualTo("abc")); 

ForConcreteType<TestController>().Configure 
    .SetterDependency(p => p.Property).Is(c => c 
     .GetInstance<ITestProperty>("Test")); 

Sinon, vous pouvez le faire:

ForRequestedType<ITestProperty>().TheDefault.Is 
    .OfConcreteType<TestProperty>() 
    .WithCtorArg("arg").EqualTo("abc"); 

ForConcreteType<TestController>().Configure 
    .SetterDependency(p => p.Property).IsTheDefault(); 

En outre, il s'agit de l'ancienne syntaxe StructureMap, vous pouvez mettre à jour vers la dernière version. Voici la nouvelle syntaxe:

For<ITestProperty>().Add<TestProperty>().Named("Test") 
    .Ctor<string>("arg").Is("abc"); 

ForConcreteType<TestController>().Configure 
    .Setter(p => p.Property).Is(c => c 
     .GetInstance<ITestProperty>("Test")); 
+0

Merci Robin. Nous avons dû mettre à niveau et utiliser l'option trois, mais cela a fonctionné parfaitement. À votre santé. –

+0

J'essaie d'utiliser ce code pour injecter un Func en tant que setter dans mon ActionFilterAttribute personnalisé. Je ne peux tout simplement pas le connecter en utilisant ce code. Des idées pourquoi? – Joel

+0

Non sans avoir vu le code, je suis loin de StructureMap depuis longtemps. Peut-être poster une nouvelle question? –

Questions connexes