Wie verwende ich StructureMap mit allgemeinen nicht geschlossenen Typen, die Scan mit einem "gierigen" Konstruktor verwenden?
Zwischen verschiedenen Stack Overflow-Fragen und Blog-Posts gibt es eine ziemlich vernünftige Menge an Dokumentation zum Thema Open Generics und StructureMap. Leider muss ich etwas vermissen, da meine Versuche @ zu benutzscan
, um die Konfiguration zusammen mit einer Klassenimplementierung durchzuführen, die einen "gierigen" Konstruktor hat, hat noch funktioniert.
Ich möchte, dass StructureMap eine Instanz der folgenden Klasse über Verweise auf die implementierte Schnittstelle abruft.ToCsvService
ist in einer nicht referenzierten Assembly namens "Infrastruktur" vorhanden.IToCsvService
existiert in einer referenzierten Assembly namens Core. Wie du sehen kannstToCsvService
hat einen "gierigen" Konstruktor.
public class ToCsvService<TSource> : IToCsvService<TSource>
{
public ToCsvService(ICollection<TSource> collection)
{
}
}
Ich informiere StructureMap überToCsvService
über dasConnectImplementationsToTypesClosing
Methode
ObjectFactory.Initialize(cfg =>
{
cfg.Scan(scan =>
{
scan.Assembly("Infrastructure");
scan.WithDefaultConventions();
// even with this call StructureMap cannot use ToCsvService
// instance of IToCsvService (though wouldn't expect it to)
scan.ConnectImplementationsToTypesClosing
(typeof(IToCsvService<>));
});
});
Von demObjectFactory.WhatDoIHave()
-Methode scheint StructureMap @ zu kennToCsvService
.
PluginType Name Description ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ IToCsvService`1 (IToCsvService`1) Scoped as: Transient 6202a7ee-89a4-4edd-831d-4867b7dd1a7e Configured Instance of Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null Configured Instance of Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Allerdings, wenn ich @ angebIToCsvService<CustomerViewModel>
In einem Controller-Konstruktor wird die Ausnahme @ ausgelös
StructureMap-Ausnahmecode: 202 Keine Standardinstanz für PluginFamily Core.Services.IToCsvService`1 [[UI.Models.MachineForm, UI, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null]], Core, Version = 1.0 definiert .0.0, Culture = neutral, PublicKeyToken = null
Ich stelle mir vor, das liegt daran, dass StructureMap keine Ahnung hat, was man dem "Gierigen" geben sollToCsvService
Konstrukteur. Gibt es eine Möglichkeit, StructureMap in die Lage zu versetzen, mit diesem Konstruktor gut zu spielen? Muss ich von einem Konstruktor wechseln und nur die Auflistungseigenschaft nach der Instanziierung festlegen?
Die FrageStrukturkarte und generische Typen details Ich versuche etwas zu tun, benutze aber keinen Scan, um dies zu tun. DasAntworte zur Verfügung gestellt vonJoshua Flanagan nutzt dieFor(x).Use(y)
-Konfiguration, die möglicherweise funktioniert, wenn ich die Baugruppe nicht gescannt habe, weil ich keine Referenz habeToCsvService
.
Bearbeite
Ich wollte herausfinden, ob StructureMap mithilfe eines anderen Mechanismus Instanzen von @ identifizierToCsvService<>
hätte einen Effekt. Es ändert sich, was in @ berichtet wiObjectFactory.WhatDoIHave()
und löst eine andere Ausnahme aus. Hier ist ein Beispiel für die Verwendung vonAddAllTypesOf
.
ObjectFactory.Initialize(cfg =>
{
cfg.Scan(scan =>
{
scan.Assembly("Infrastructure");
scan.WithDefaultConventions();
scan.AddAllTypesOf(typeof(IToCsvService<>));
});
});
Nach dem Verwenden des oben genannten Dumps vonObjectFactory.WhatDoIHave()
ist
PluginType Name Description -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- IToCsvService`1 (IToCsvService`1) Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null Configured Instance of Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null Scoped as: Transient Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null Configured Instance of Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- IToCsvService`1 (IToCsvService`1) Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null Configured Instance of Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null Scoped as: Transient Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null Configured Instance of Infrastructure.Services.ToCsvService`1, Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
it dieser Konfiguration werfe ich diese Ausnahme:
StructureMap-Ausnahmecode: 202 Keine Standardinstanz für PluginFamily System.Collections.Generic.ICollection`1 [[UI.Models.MachineForm, UI, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null]], mscorlib, Version definiert = 4.0.0.0, Kultur = neutral, PublicKeyToken = b77a5c561934e089
Für mich gibt die Ausnahme an, dass StructureMap weiß, dass es ein @ benötigICollection<MachineForm>
instanziierenToCsvService
weiß aber nicht woher es kommt. Welches geht an Jimmy's Kommentar von unten zur Verwendung von StructureMap undConstructor Setter Einspritzung. Dies scheint jedoch nicht möglich zu sein, ohne einen expliziten Verweis auf die Infrastructure-Assembly hinzuzufügen.