2016-07-26 135 views
1

我在我的應用程序組件,看起來像這樣的接口:Autofac工廠靜態方法

interface ILogger : IService 
{ 
    Task LogAsync(Message message); 
} 

我需要使用一個靜態方法來構建這些實例:

ILogger logger = ServiceProxy.Create<ILogger>(new Uri(...), new ServicePartitionKey(...)); 

這對於我的單元測試是有問題的,因此我正在使用Autofac與代表工廠進行實例化:

public class LogConsumer 
{ 
    private Func<Uri, ServicePartitionKey, ILogger> _logFactory; 
    public LogConsumer(Func<Uri, ServicePartitionKey, ILogger> logFactory) 
    { 
     _logFactory = logFactory; 
    } 

    public async Task MethodThatUsesLogger() 
    { 
     ILogger logger = _logFactory(new Uri(...), new ServicePartitionKey(...)); 

     await logger.LogAsync(...);   
    } 
} 

I我在註冊Autofac像這樣:

builder.Register<ILogger>(ctx => (uri, key) => ServiceProxy.Create<ILogger>(uri, key)); 
  • 如果我需要以同樣的方式來註冊10個不同的接口,我能做到這一點與泛型一條線?
  • 有沒有辦法做到這一點,而不注入Func,並更像Ninject.Extensions.Factory?
+0

你有沒有使用[周圍語境模式(HTTPS考慮: //relentlessdevelopment.wordpress.com/2013/09/30/testing-datetimes-and-other-things-with-an-ambient-context/)?這種模式特別適合於諸如伐木這樣的交叉問題。 –

+0

這不完全用於記錄。它是Service Fabric服務的遠程接口。 ILogger只是一個簡單的界面,我用它爲例。我認爲這種模式仍然適用。 – Dismissile

+0

@MthetheWWatson,雖然這似乎很多代碼,如果我不得不這樣做10個不同的代理接口。 – Dismissile

回答

3

您可以通過實現IRegistrationSource

class FactoryRegistrationSource<TService> : IRegistrationSource 
{ 

    public Boolean IsAdapterForIndividualComponents 
    { 
     get 
     { 
      return false; 
     } 
    } 

    public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor) 
    { 
     IServiceWithType typedService = service as IServiceWithType; 
     if (typedService == null) 
     { 
      yield break; 
     } 

     if (typedService.ServiceType == typeof(TService)) 
     { 
      IComponentRegistration registration = RegistrationBuilder.ForDelegate<Func<Uri, TService>>((c, p) => ((Uri uri) => Factory.Get<TService>(uri))) 
                    .CreateRegistration(); 

      yield return registration; 
     } 
    } 
} 

你想要什麼你就得這樣註冊它:

builder.RegisterSource(new FactoryRegistrationSource<ILogger>());