2016-11-30 3 views
0

저는 autofac에 새로운 것이있어서 문제가 있습니다. 나는 웹 API를 사용하고 내가 이렇게 내 모듈을 설정 한 : 나는 다른 범위로 고민하고autofac 해결 의존성

public class CormarModule : Module 
{ 


    // Fields 
    private readonly string _connectionStringName; 
    private readonly connectionType _connection; 

    /// <summary> 
    /// Default constructor 
    /// </summary> 
    public CormarModule() { 
     _connectionStringName = ConfigurationManager.AppSettings["ConnectionStringName"]; 
     _connection = _connectionStringName.ToUpper().Contains("LIVE") ? connectionType.Live : connectionType.Test; 
    } 

    protected override void Load(ContainerBuilder builder) 
    { 

     // Singletons 
     builder.RegisterType<DatabaseContext>().As<DatabaseContext>().SingleInstance(); 
     builder.RegisterType<UnitOfWork<DatabaseContext>>().As<IUnitOfWork>().SingleInstance(); 
     builder.Register(c => new OracleUnitOfWork(_connectionStringName)).As<IOracleUnitOfWork>().SingleInstance(); 
     builder.Register(c => new AdvancedEncryptionStandardProvider(ConfigurationManager.AppSettings["rm:key"], ConfigurationManager.AppSettings["rm:secret"])).As<IAdvancedEncryptionStandardProvider>().SingleInstance(); 

     // Register our services   
     builder.RegisterType<AccountService>().As<IAccountService>(); 
     builder.RegisterType<DeliveryInformationService>().As<IDeliveryInformationService>(); 
     builder.RegisterType<EmailService>().As<IEmailService>(); 
     builder.RegisterType<LogService>().As<ILogService>(); 
     builder.RegisterType<OrderService>().As<IOrderService>(); 
     builder.RegisterType<OrderLineService>().As<IOrderLineService>(); 
     builder.RegisterType<PaymentHistoryService>().As<IPaymentHistoryService>(); 
     builder.RegisterType<PrincipleProvider>().As<IPrincipleProvider>(); 
     builder.RegisterType<ProductService>().As<IProductService>(); 
     builder.RegisterType<RefreshTokenService>().As<IRefreshTokenService>(); 
     builder.RegisterType<StockService>().As<IStockService>(); 
     builder.Register(c => new UserStore<User>(c.Resolve<DatabaseContext>())).As<IUserStore<User>>(); 

     // Single instance 
     builder.RegisterType<OAuthProvider>().As<OAuthProvider>(); 
     builder.RegisterType<LogProvider>().As<ILogProvider>(); 
     builder.RegisterType<RefreshTokenProvider>().As<IAuthenticationTokenProvider>(); 
     builder.Register(c => new SendGridProvider(c.Resolve<IUnitOfWork>(), c.Resolve<IEmailService>(), ConfigurationManager.AppSettings["SendGridApiKey"])).As<ISendGridProvider>(); 
     builder.Register(c => new UserProvider(_connectionStringName, c.Resolve<IUserStore<User>>(), c.Resolve<IAdvancedEncryptionStandardProvider>(), c.Resolve<ISendGridProvider>())).As<IUserProvider>(); 

     // Per request 
     builder.RegisterType<DeliveryInformationProvider>().As<IDeliveryInformationProvider>().InstancePerRequest(); 
     builder.RegisterType<JournalProvider>().As<IJournalProvider>().InstancePerRequest(); 
     builder.RegisterType<StockProvider>().As<IStockProvider>().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies).InstancePerRequest(); 

     builder.Register(c => new AccountProvider(_connection, c.Resolve<IAccountService>(), c.Resolve<IPrincipleProvider>(), c.Resolve<IAdvancedEncryptionStandardProvider>(), c.Resolve<IPaymentHistoryService>())).As<IAccountProvider>().InstancePerRequest(); 
     builder.Register(c => new ProductProvider(_connection, c.Resolve<IProductService>())).As<IProductProvider>().InstancePerRequest(); 
     builder.Register(c => new OrderProvider(_connection, c.Resolve<IOrderService>(), c.Resolve<IPrincipleProvider>(), c.Resolve<IAdvancedEncryptionStandardProvider>())).As<IOrderProvider>().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies).InstancePerRequest(); 
     builder.Register(c => new OrderLineProvider(_connection, c.Resolve<IOrderLineService>(), c.Resolve<IPrincipleProvider>(), c.Resolve<IAdvancedEncryptionStandardProvider>())).As<IOrderLineProvider>().InstancePerRequest(); 
    } 
} 

. 문제를 설명하기 전에 약간의 배경 지식.

제공자 필수 서비스을 가지며 각 컨트롤러는 하나 이상의 주입 제공자를 갖는다. 각 공급자에는 공급자이있을 수 있습니다.이 메서드는 메서드가 해당 공급자를 호출 할 때만 확인해야합니다.

문제는 설정하는 방법을 모르겠다는 것입니다. 나는 생성자와 메서드에 평생 범위를 삽입하려고했으나 필요한 공급자을 해결했지만이 방법은 좋지 않습니다. 또한 새로운 인스턴스를 만드는 것입니다. 요청 당 하나의 인스턴스를 사용하고 싶습니다. 요청이 필요한 경우에만 필요합니다.

나는 그것이 의미가 있기를 바랍니다. 누군가 도와 드릴 수 있기를 바랍니다.

답변

1

IMO, 꽤 잘하고 있습니다.

당신이 필요로하는 것은 Func<Provider>에 의존하는 것입니다. Autofac에 Func<>을 요청하면 .Resolve<Provider> 대신 호출되는 팩토리 메서드가 반환됩니다.

설명서는 herehere을 참조하십시오.

당신은이 방법을 쓸 수 있습니다 :

private OptionalProvider _instance; 
private Func<OptionalProvider> _providerGetter; 

public OptionalProvider Prov 
{ 
    get { return _instance ?? (_instance = _providerGetter()); } 
} 

public MyProvider(Func<OptionalProvider> getter) 
{ 
    _providerGetter = getter; 
} 

public void MethodRequiringOptionalProvider() 
{ 
    // just use property Prov and let Autofac handle the rest 
} 

또 다른 제안 : 대신 직접 _connection 문자열 매개 변수를 주입, 그냥하는 CormarConfig 클래스를 생성 모든 구성 옵션을 저장하는 .RegisterInstance에 등록 할 수 있습니다. 이 방법을 사용하면 RegisterType을 호출하고 Autofac이 모든 유형 매개 변수를 해결하도록합니다 (당신은 그 못생긴 Resolve 호출을 제거합니다).

모든 서비스가 공통 조상에서 상속 받거나 공통 인터페이스를 구현하는 경우 Assembly ScanningAsImplementedInterfaces을 통해 모두 등록 할 수 있습니다. 모듈에있는 모든 혼란을 없앨 수 있습니다.