1

我有一个似乎相对常见的情况。我需要注入一个需要构造函数的依赖项。

我有一个如下所示的存储库:

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)
4

2 回答 2

0

在我看来,您尝试注入处理程序的具体类型对于端点本身来说应该是未知的。

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

我喜欢通过在类上放置自定义属性来通过“选择加入”来选择我的类型:

[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();
    }
}
于 2013-10-15T11:13:05.007 回答
0

在我的 ApprovalRepository 中,出现了一些奇怪的代码,即:

#region Public Properties

public IApprovalRepository Repository { get; set; }

#endregion

NServiceBus 然后试图自动注入该属性。结果,ApprovalRepository 采用了 IApprovalRepository。哎呀。我的错。这现在解释了错误:

Server.PlaceApprovalHandler -> Server.ApprovalRepository -> Server.ApprovalRepository
于 2013-04-12T08:52:21.227 回答