2012-07-26 11 views
8

Używam autofac jako Ioc Container. mam trzy klasy:Jak zarejestrować te klasy w Autofac

class Service 
{ 
    public Service(Repository rep,UnitOfWork context){} 

} 

Class Repository 
{ 
    public Repository(UnitOfWork context){} 
} 

class UnitOfWork{} 

Service Repository i potrzebują takiej samej instancji UnitOfWork

Jak to zrobić? i jak wirte go w XmlConfiguration

+0

I przepraszam, mój angielski jest słaby – DotDot

Odpowiedz

30

EDIT: I misread tym i myślałem, że to pytanie o sposób korzystania autofac zarejestrować zależności. Jeśli chcesz zachować ten sam UnitOfWork, musisz zmienić czas życia instancji na coś. Jeśli używasz tego w aplikacji ASP.NET lub WCF można zarejestrować zależności tak:

typeBuilder.RegisterType<UnitOfWork>().InstancePerLifetimeScope(); 
typeBuilder.RegisterType<Repository>(); 
typeBuilder.RegisterType<Service>(); 

Pierwszą rzeczą, którą trzeba zrobić, aby wykorzystać pojemnik jak Autofac to zarejestrować wszystkie swoje zależności. W Autofac możesz to zrobić na kilka sposobów, ale wszystkie z nich polegają na użyciu ContainerBuilder. Numer ContainerBuilder opiera się na metodach rozszerzania, dlatego upewnij się, że masz instrukcję using dla przestrzeni nazw Autofac.

można jednoznacznie określić metody fabryczne:

// Explicitly 
var builder = new ContainerBuilder(); 
builder.Register<UnitOfWork>(b => new UnitOfWork()); 
builder.Register<Repository>(b => new Repository(b.Resolve<UnitOfWork>())); 
builder.Register(b => new Service(b.Resolve<Repository>(), b.Resolve<UnitOfWork>())); 

Korzystanie ContainerBuilder mamy dostęp metodę Register<>() dostarczenie interfejsu serwisowego (co jest, jak będziemy się pytać pojemnik za usługę) w tym przypadku , Nie używam interfejsów, tylko właściwy typ. Za każdym razem, gdy poprosisz kontener o numer UnitOfWork, użyje on metody fabrycznej new UnitOfWork() do wygenerowania. W prawdziwym życiu prawdopodobnie prosiłbyś o IUnitOfWork. Może to być trochę gadatliwe, ale jest bardzo przydatne, gdy potrzebujesz niestandardowej logiki do tworzenia zależności.

Można używać budowniczych jak każdego innego kontenera zależności i po prostu zarejestrować typy.

// Implicitly 
var typeBuilder = new ContainerBuilder(); 
typeBuilder.RegisterType<UnitOfWork>(); 
typeBuilder.RegisterType<Repository>(); 
typeBuilder.RegisterType<Service>(); 

Podejście to opiera się na rejestracji wszystkie zależności potrzebne do zbudowania klasy. Kontener użyje refleksji do rozwiązania wszelkich argumentów konstruktora. Jeśli argument nie zostanie zarejestrowany, kontener wygeneruje wyjątek z typem, którego nie może rozwiązać. W tym przypadku usługa jest zależna od UnitOfWork i Repository. Repository ma również zależność od UnitOfWork. Te zależności są wyrażone jako argumenty konstruktora. Aby zażądać od kontenera Repository lub Service, muszą zostać zarejestrowane wszystkie zależności:

Można zastosować podejście konfiguracyjne.

Jeśli używasz pliku app.config, można określić plik konfiguracyjny tak:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
    <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/> 
    </configSections> 

    <autofac defaultAssembly="AutoFacTest"> 
    <components> 
     <component 
       type="AutoFacTest.Repository, AutoFacTest" 
       service="AutoFacTest.Repository" /> 

     <component 
       type="AutoFacTest.UnitOfWork, AutoFacTest" 
       service="AutoFacTest.UnitOfWork" /> 

     <component 
       type="AutoFacTest.Service, AutoFacTest" 
       service="AutoFacTest.Service" /> 
    </components> 
    </autofac> 
</configuration> 

pierwsze należy zauważyć, że mamy do definiowania sekcji config (zauważyć <ConfigSections>). Następnie możemy utworzyć sekcję <autofac>, która definiuje wszystkie nasze zależności. Notacja jest dość prosta, w zasadzie dla każdego zależności tworzony jest <component>.Każdy komponent ma atrybut service, który definiuje typ, który będzie żądany. Istnieje również atrybut type, który definiuje obiekt, który ma zostać utworzony, gdy żądana jest instancja usługi. Jest to analogiczne do builder.Register<UnitOfWork>(b => new UnitOfWork()), gdzie UnitOfWork jest żądaną usługą (iw tym przypadku) również typem, który ma zostać utworzony.

Aby utworzyć konstruktor za pomocą konfiguracji, użyj ConfigurationSettingsReader()

// Config 
var configBuilder = new ContainerBuilder(); 
configBuilder.RegisterModule(new ConfigurationSettingsReader("autofac")); 

trzeba przejść w imię swojej sekcji konfiguracji (w tym przypadku autofac). Po skonfigurowaniu zależności należy zbudować kontener. ContainerBuilder zawiera metodę, aby to zrobić:

var container = builder.Build(); 
var typeContainer = typeBuilder.Build(); 
var configContainer = configBuilder.Build(); 

A skoro masz pojemnik, można zażądać wystąpień usługi:

container.Resolve<Service>().DoAwesomeness(); 
typeContainer.Resolve<Service>().DoAwesomeness(); 
configContainer.Resolve<Service>().DoAwesomeness(); 

kompletny program:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Autofac; 
using Autofac.Configuration; 

namespace AutoFacTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // Explicitly 
      var builder = new ContainerBuilder(); 
      builder.Register<UnitOfWork>(b => new UnitOfWork()); 
      builder.Register<Repository>(b => new Repository(b.Resolve<UnitOfWork>())); 

      builder.Register(b => new Service(b.Resolve<Repository>(), b.Resolve<UnitOfWork>())); 

      // Implicitly 
      var typeBuilder = new ContainerBuilder(); 
      typeBuilder.RegisterType<UnitOfWork>(); 
      typeBuilder.RegisterType<Repository>(); 
      typeBuilder.RegisterType<Service>(); 

      // Config 
      var configBuilder = new ContainerBuilder(); 
      configBuilder.RegisterModule(new ConfigurationSettingsReader("autofac")); 

      var container = builder.Build(); 
      var typeContainer = typeBuilder.Build(); 
      var configContainer = configBuilder.Build(); 


      container.Resolve<Service>().DoAwesomeness(); 
      typeContainer.Resolve<Service>().DoAwesomeness(); 
      configContainer.Resolve<Service>().DoAwesomeness(); 
      Console.Read(); 
     } 
    } 

    public class Repository 
    { 
     private readonly UnitOfWork _unitOfWork; 
     public Repository(UnitOfWork uow) 
     { 
      _unitOfWork = uow; 
     } 

     public void PrintStuff(string text) 
     { 
      Console.WriteLine(text); 
     } 
    } 

    public class Service 
    { 
     private readonly Repository _repository; 
     private readonly UnitOfWork _unitOfWork; 

     public Service(Repository repo, UnitOfWork uow) 
     { 
      _repository = repo; 
      _unitOfWork = uow; 
     } 
     public void DoAwesomeness() 
     { 
      _repository.PrintStuff("Did awesome stuff!"); 
      _unitOfWork.Commit(); 
     } 
    } 

    public class UnitOfWork 
    { 
     public bool Commit() 
     { 
      return true; 
     } 
    } 


} 
+0

Nie mam konstruktora '' 'ConfigurationSettingsReader''', skąd pochodzi? – HoKy22

+0

http://stackoverflow.com/questions/39364698/autofac-upgrade-to-version-4-0-0-is-missing-configurationsettingsreader Jak to zrobić w Autofac 4.2? – HoKy22