1

J'ai un problème .... De peur que dire que j'ai une classe comme celle-ci:StructureMap type de résolution avec des paramètres

public class A: InterfaceA 
{ 
    private FileInfo _fileInfo = null; 
    public A(FileInfo fileInfo) 
    { 
     this._fileInfo = fileInfo; 
    } 

    ... 
} 

et un autre:

public class B: InterfaceB 
{ 
    private A _classA = null; 
    public B(A classA) 
    { 
     this._classA = classA; 
    } 

    public void Do() 
    { 
     FileInfo fi = new FileInfo(...); 
     _classA.DoSomething(); 
    } 
} 

Maintenant, j'ai installé StructureMap enregistre comme ceci:

For<InterfaceA>().Use<A>(); 
For<InterfaceB>().Use<B>(); 

et quand j'exécute B.Do() structuremap va lancer une erreur car il n'y a pas d'entrée de registre pour le paramètre FileInfo. Le paramètre de classe A (FileInfo) est construit dans la classe B; Je sais que je peux faire: ObjectFactor.GetInstance() et passer les paramètres, mais je veux injection de dépendance pas fournisseur de services. Et je le veux quand je fais ObjectFactory.GetInstance(), pour construire un graphe d'objet entier.

Comment faire?

Répondre

4

Vous pouvez utiliser l'instruction Ctor pour indiquer à SM les objets à utiliser pour les paramètres Ctor.

var myFile = new FileInfo(...); 
For<InterfaceA>.Use<A>().Ctor<FileInfo>().Is(myFile); 

En savoir plus sur les arguments Ctor here.

Edit: Dans le cas où le nom de fichier est inconnu jusqu'à ce que l'exécution de la méthode Do en B, vous devez reporter la création de l'A-objet jusqu'à ce que la méthode do est exécutée. Pour ce faire, vous pouvez utiliser une usine, soit codée à la main ou Func/Lazy.

Pour une approche Func vous pouvez changer votre B pour prendre une Func de A comme la dépendance cteur:

public class B : InterfaceB 
{ 
    private readonly Func<string, InterfaceA> _aBuilder; 
    public B(Func<string, InterfaceA> aBuilder) 
    { 
    _aBuilder = aBuilder; 
    } 

    public void Do() 
    { 
    InterfaceA anA = _aBuilder("fileName"); 
    anA.DoSomething(); 
    } 
} 

sangle d'amorçage à l'aide:

ObjectFactory.Initialize(
    c=> 
    { 
    c.For<InterfaceA>().Use<A>(); 
    c.For<Func<string, InterfaceA>>().Use(d => 
     new Func<string, InterfaceA>(s => 
     ObjectFactory.With(new FileInfo(s)).GetInstance<InterfaceA>())); 
    c.For<InterfaceB>().Use<B>(); 
    } 
); 
+0

Si le nom de fichier n'est pas connu avant l'exécution de la méthode Do, vous devez soit opter pour une approche en usine, soit envisager de passer le fichier à la méthode. – PHeiberg

+0

Édité ma réponse pour inclure une approche d'usine. – PHeiberg

Questions connexes