2016-07-14 8 views
1

Ich habe eine Klasse, die AutoFac verwendet, um einen Container aus den Assemblys im Binärordner zu erstellen. Dieses im Wesentlichen iteriert über die DLL und registriert Klassen mit einer Schnittstelle:Wie ändere ich den Gültigkeitsbereich während des Autofac-Assembly-Scans und der Registrierung selektiv?

private static void RegisterAssembly(ContainerBuilder builder, string assemblyNamePattern) 
    { 
     // Get the path to the currently executing assembly. We will load dll's from here only. 
     var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 
     if (String.IsNullOrWhiteSpace(path)) 
      return; 

     // Get a list of all the assemblies in this folder 
     var assembliesToRegister = (Directory.EnumerateFiles(path, assemblyNamePattern, SearchOption.TopDirectoryOnly) 
       .Select(Assembly.LoadFrom) 
       .ToArray()); 

     // Register the dll's 
     builder.RegisterAssemblyTypes(assembliesToRegister).AsImplementedInterfaces(); 
    } 

Das funktioniert gut und ich kann Instanzen der Klassen erstellen, die ich brauche. Das Problem, das ich habe, ist, dass es einige dieser Klassen gibt, die Singletons sind (zum Beispiel Redis Caching), also müssen sie als solche registriert werden. Im Code sind sie die Faulen definiert mit <>:

private static readonly Lazy<CacheManager> _instance = new Lazy<CacheManager>(() => new CacheManager()); 
    public static ICacheManager Instance 
    { 
     get { return _instance.Value; } 
    } 

Was ich frage mich, ob es eine Möglichkeit ist Autofac zu sagen, dass bestimmte Klassen als Singletons registriert werden müssen. Ich schätze, ich kann den Container durchgehen, nachdem er erstellt wurde, und bestimmte Definitionen in Singletons umwandeln, aber es wäre viel zuverlässiger, wenn ich Autofac dazu bringen könnte, dies automatisch bei der Registrierung zu tun.

+0

Welche Version von Autofac verwenden Sie? –

+0

Version 3.5.2 (Entschuldigung, sollte das zum Beitrag hinzugefügt haben). Ich habe einige Fortschritte gemacht, dass ich jetzt die Assemblys registriere und verwende, um die Singleton-Klassen auszuschließen. Ich registriere diese dann separat als SingleInstance(). ExternallyOwned(). Keine gute Lösung, aber schnell lernen! – SteveB

+0

Die Verwendung von LINQ zum Einschließen/Ausschließen bestimmter Typen ist eigentlich die Antwort auf Ihre Frage - Sie sollten dies posten und Ihre eigene Antwort akzeptieren. –

Antwort

1

Als günstige Lösung, wenn die DLL gescannt werden, können Sie eine oder mehrere Schnittstellen ausschließen:

 // Register the dll's, except the singleton ones. 
     builder.RegisterAssemblyTypes(assembliesToRegister) 
       .AsImplementedInterfaces() 
       .Except<IOne>() 
       .Except<ITwo>(); 

Dies alles erlaubt, außer die Singletons automatisch registriert werden. Als nächstes registrieren die Singletons:

AddSingletonInstance<IOne>(builder, assembliesToRegister, "OneType"); 
AddSingletonInstance<ITwo>(builder, assembliesToRegister, "TwoType"); 

Diese auf einer generischen Methode beruht, die die Montageliste zuvor erstellt sucht:

private static void AddSingletonInstance<T>(ContainerBuilder builder, Assembly[] assembliesToRegister, string typeName) 
    { 
     var singletonType = (from asm in assembliesToRegister 
         from tt in asm.DefinedTypes 
         where tt.Name == typeName 
         select tt).FirstOrDefault(); 

     if (singletonType != null) 
      builder.RegisterType(singletonType).As<T>().SingleInstance().ExternallyOwned(); 
    } 

Es ist nicht ideal, aber es funktioniert.

Verwandte Themen