2013-04-11 2 views
1

У меня есть то, что, казалось бы, относительно распространенным сценарием. Мне нужно ввести зависимость, которая требует конструктора.Как настроить инъекции конструктора в NServiceBus

У меня есть репозиторий, который выглядит следующим образом:

public class ApprovalRepository : IApprovalRepository 
{ 
    private readonly MongoCollection<Approval> _collection; 

    public ApprovalRepository(MongoDatabase database) 
    { 
     this._collection = database.GetCollection<Approval>("Approvals"); 
    } 

    // ... 
} 

конечная точка конфигурации, которая выглядит следующим образом:

public class EndpointConfig : IConfigureThisEndpoint, 
    AsA_Server, IWantCustomInitialization 
{ 
    public void Init() 
    { 
     NServiceBus.Configure.With().DefaultBuilder().JsonSerializer(); 
    } 
} 

и обработчик, который выглядит следующим образом:

public class PlaceApprovalHandler : IHandleMessages<PlaceApproval> 
{ 
    public IApprovalRepository ApprovalRepository { get; set; } 

    public void Handle(PlaceApproval message) 
    { 
     // 
     ApprovalRepository.Save(
      new Approval 
       { 
        Id = message.Id, 
        Message = message.MessageText, 
        ProcessedOn = DateTime.UtcNow 
       }); 
    } 
} 

Затем у меня есть класс для выполнения пользовательской инициализации:

public class ConfigureDependencies : IWantCustomInitialization 
{ 
    public void Init() 
    { 
     // configure Mongo 
     var client = new MongoClient("mongodb://localhost:27017/?safe=true"); 
     var server = client.GetServer(); 
     var database = server.GetDatabase("ServiceBusTest"); 

     Configure.Instance.Configurer.RegisterSingleton<IApprovalRepository>(new ApprovalRepository(database)); 
    } 
} 

В результате ошибка:

2013-04-11 17:01:03,945 [Worker.13] WARN NServiceBus.Unicast.UnicastBus [(null)] <(null)> - PlaceApprovalHandler failed handling message. 
Autofac.Core.DependencyResolutionException: Circular component dependency detected: Server.PlaceApprovalHandler -> Server.ApprovalRepository -> Server.ApprovalRepository. 
    at Autofac.Core.Resolving.CircularDependencyDetector.CheckForCircularDependency(IComponentRegistration registration, Stack`1 activationStack, Int32 callDepth) in :line 0 
    at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) in :line 0 

Я не знаком с Autofac. Я также попытался следующие, которые также имели аналогичный результат:

Configure.Instance.Configurer.ConfigureComponent(() => new ApprovalRepository(database), DependencyLifecycle.SingleInstance) 

ответ

0

В моей ApprovalRepository, некоторые нечетные код закралась в, а именно:

#region Public Properties 

public IApprovalRepository Repository { get; set; } 

#endregion 

NServiceBus затем пытается автоматически вводить эту собственность. В результате утверждениеRepository заняло IApprovalRepository. По электронной почте Ой. Виноват. Теперь это объясняет ошибку:

Server.PlaceApprovalHandler -> Server.ApprovalRepository -> Server.ApprovalRepository 
0

Мне кажется, что конкретные типы вы пытаетесь внедрить в обработчик должны быть неизвестны самой конечной точкой.

https://code.google.com/p/autofac/wiki/Scanning

Мне нравится выбирать мои типы с помощью "Opt-In", поставив пользовательский атрибут класса:

[AttributeUsage(AttributeTargets.Class)] 
public class RegisterServiceAttribute : Attribute {} 

Затем выберите типы, как это:

builder.RegisterAssemblyTypes(assemblies) 
    .Where(t => t.GetCustomAttributes(typeof (RegisterServiceAttribute), false).Any()) 
    .AsSelf() 
    .AsImplementedInterfaces(); 

в качестве примера того, что я делаю:

public class EndpointConfig : IConfigureThisEndpoint, IWantCustomInitialization, AsA_Server, UsingTransport<SqlServer> 
{ 
    public void Init() 
    { 
     var builder = new ContainerBuilder(); 

     builder.RegisterAssemblyTypes(GetAllAssemblies()) 
      .Where(t => t.GetCustomAttributes(typeof(ProviderAttribute), false).Any()) 
      .AsSelf() 
      .AsImplementedInterfaces(); 

     Configure 
      .With() 
      .UseTransport<SqlServer>() 
      .AutofacBuilder(builder.Build()) 
      .UseNHibernateTimeoutPersister() 
      .UseNHibernateSagaPersister() 
      .UnicastBus(); 
    } 

    private static Assembly[] GetAllAssemblies() 
    { 
     var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 

     return Directory.GetFiles(path, "*.dll").Select(Assembly.LoadFile).ToArray(); 
    } 
} 
Смежные вопросы