Ninject在域事件上多次创建单例实例

时间:2014-03-07 11:17:10

标签: c# asp.net-mvc dependency-injection domain-driven-design ninject

域名服务

public void MyDomainService {

    void DoSomething() {
        Raise<MyDomainEvent>(new DomainEvent());
    }

}

Singleton Application Service

public void SingletonApplicationService {
    // Handles MyDomainEvent

    private int _myRandomId = new RandomId();

    public SingletonApplicationService() {
        _logger.Info("Hello, I'm " + _myRandomId + ". I got resolved.");
    }

    public void Handle(DomainEvent event) {
        _logger.Info("Hello, I'm " + _myRandomId + ". I received a domain event.");
    }

}

内核绑定

Kernel.Bind<IDomainService>().To<DomainService>()
    .InRequestScope();
Kernel.Bind<ISingletonApplicationService>()
    .To<SingletonApplicationService>()
    .InSingletonScope();
Kernel.Bind<IDomainEventHandler<MyDomainEvent>>()
    .To<SingletonApplicationService>();
     // tried as singleton and per request

应用程序启动

Kernel.Get<ISingletonApplicationService>();

var domainService = Kernel.Get<IDomainService>();
domainService.DoSomething();

这会产生以下日志:

"Hello, I'm 421. I got resolved."
// domain event occurs here
"Hello, I'm 455. I got resolved."
"Hello, I'm 421. I received a domain event.");
"Hello, I'm 455. I received a domain event."); // and I crash because of that!

1 个答案:

答案 0 :(得分:1)

由于您正在使用Ninject,因此您还需要注册IDomainEventHandler<MyDomainEvent>以拥有单一作用域as default scope is transient

Kernel.Bind<IDomainEventHandler<MyDomainEvent>>()
    .To<SingletonApplicationService>()
    .InSingletonScope();

但我相信每个服务都有一个单例实例,即ISingletonApplicationService的单例实例和IDomainEventHandler<MyDomainEvent>的单例实例。您可能希望两者都解析为相同的单例实例。实现这一目标并实现懒惰实例化的一种方法是

Kernel.Bind<SingletonApplicationService>().ToSelf().InSingletonScope();
Kernel.Bind<ISingletonApplicationService >().ToMethod(
    c => c.Kernel.Get<SingletonApplicationService>());
Kernel.Bind<IDomainEventHandler<MyDomainEvent>>().ToMethod(
    c => c.Kernel.Get<SingletonApplicationService>());