2016-07-26 109 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>());