2010-01-25 7 views
5

In meiner Registrierung verbunden setzen Ich habeStructureMap: Wie Lebenszyklus auf Typen mit ConnectImplementationsToTypesClosing

Scan(scanner => 
     { 
      scanner.AssemblyContainingType<EmailValidation>(); 
      scanner.ConnectImplementationsToTypesClosing(typeof(IValidation<>)); 
     }); 

Was soll ich tun, um diese alle als Singletons zu definieren?

Auch als eine Nebensache zu dieser Frage gibt es einen Grund, nicht alles zu definieren, das als ein Singleton-Objekt stateless ist, das in StructureMap registriert wird?

Antwort

11

Kevins Antwort ist korrekt für Versionen 2.5.4 und älter. In der aktuellen StructureMap Stamm (und wenn 2.5.5+ freigegeben wird), können Sie jetzt tun:

Scan(scanner => 
{ 
    scanner.AssemblyContainingType<EmailValidation>(); 
    scanner.ConnectImplementationsToTypesClosing(typeof(IValidation<>)) 
      .OnAddedPluginTypes(t => t.Singleton()); 
}); 
+0

sehr schön hinzugefügt, kann nicht auf 2.5.5 warten! –

+0

Switched die Antwort auf diese, um mehr in Einklang mit den aktuellen Zeiten. –

1

Die Assembly-Scanner-Methode ConnectImplementationsToTypesClosing verwendet eine IRegistrationConvention, um die Aufgabe zu erledigen. Dazu habe ich den generischen Connection Scanner von StructureMap kopiert und aktualisiert, um auch einen Bereich zu nutzen. Als nächstes habe ich eine praktische Assembly-Scanner-Erweiterungsmethode erstellt, um sie als syntaktischen Zucker zu verwenden.

public class GenericConnectionScannerWithScope : IRegistrationConvention 
{ 
    private readonly Type _openType; 
    private readonly InstanceScope _instanceScope; 

    public GenericConnectionScannerWithScope(Type openType, InstanceScope instanceScope) 
    { 
     _openType = openType; 
     _instanceScope = instanceScope; 

     if (!_openType.IsOpenGeneric()) 
     { 
      throw new ApplicationException("This scanning convention can only be used with open generic types"); 
     } 
    } 

    public void Process(Type type, Registry registry) 
    { 
     Type interfaceType = type.FindInterfaceThatCloses(_openType); 
     if (interfaceType != null) 
     { 
      registry.For(interfaceType).LifecycleIs(_instanceScope).Add(type); 
     } 
    } 
} 

public static class StructureMapConfigurationExtensions 
{ 
    public static void ConnectImplementationsToSingletonTypesClosing(this IAssemblyScanner assemblyScanner, Type openGenericType) 
    { 
     assemblyScanner.With(new GenericConnectionScannerWithScope(openGenericType, InstanceScope.Singleton)); 
    } 
} 

Hier ist der entsprechende Setup-Code.

Scan(scanner => 
    { 
     scanner.ConnectImplementationsToSingletonTypesClosing(typeof(IValidation<>)); 
    }); 

Hoffe das hilft.

+0

Das sieht definitiv wie eine Lösung, es ist dumm dies für etwas so einfach getan werden muss, aber das sieht sehr ähnlich zu einem Post, den ich früher in der SM-Gruppe gesehen habe, denke ich, dass Jeremy hinzufügen könnte, dass er eine Möglichkeit hinzufügt, ohne dass man seine eigene Konvention in 2.5.5 implementieren muss und nun seinen Beitrag sieht, macht es viel Sinn, worum es ging. –

+0

Der Beitrag wurde nicht angezeigt. Ich arbeite mit Jeremy. Um meine Lösung zu erstellen, habe ich mir einfach die StructureMap-Quelle geschnappt und herausgefunden, wie er das gemacht hat, und sie entsprechend Ihrer Anfrage angepasst. Es könnte von etwas mehr Flexibilität oder besserer Integration mit der SM-Konfiguration DSL profitieren, aber das wird Sie für jetzt loslegen. Genießen. – KevM