简体   繁体   中英

Is possible Ninject static property binding?

Does ninject works for static property bindings?

I set IEventHandlerFactory with Ninject,

public class ServiceModule: NinjectModule
{
    public override void Load()
    {
      Kernel.Bind<IEventHandlerFactory>().To<EventHandlerFactoryService>();
    }
}

And my static class

public static class DomainEvents
{
    public static IEventHandlerFactory EventHandlerFactory { get; set; }

    public static void Raise<T>(T domainEvent) 
    {
        EventHandlerFactory
            .GetDomainEventHandlersFor(event)
            .ForEach(h => h.Handle(event));
    }
}

But this does not bind to static property.

DomainEvents.EventHandlerFactory is Null

Is there any way to bind property?

Since ninject doesn't have a concept of dividing "creating all bindings" and "using the kernel", there's of course no extension point for "tell me when the kernel is done with all bindings so i can do something". With a static class it also doesn't make sense to request it from the kernel.

So the obvious answer is: no.

Of course, the obvious solution is just to extend your code where you're done building up the kernel (probably close to where you do var kernel = new StandardKernel() ) with a call like

DomainEvents.EventHandlerFactory = kernel.Get<IEventHandlerFactory>();

Alternative 1 - tying initialization to activation of another type

If that initialization should be tied to the activation of another type, let's say IFoo , you can also do:

kernel.Bind<IFoo>()
      .To<Foo>()
      .InSingletonScope()
      .OnActivation(x => 
          DomainEvents.EventHandlerFactory = kernel.Get<IEventHandlerFactory>());

Alternative 2 - tying initialization to loading of a NinjectModule

You can sublcass NinjectModule and in it's Load you can initialize the static property. This works in case you can make sure the module is only loaded after the kernel is sufficiently initialized to create an IEventHandlerFactory .

Disclaimer

Both alternatives probably suck because their not clear and not straight forward. They hide a dependency deep in some place. I'd only use one of these if the first approach is not feasible, for example because your writing a plugin and there's no extension point post-kernel initialization.

Do you really need DomainEvents class to be static?

Maybe you can do as follows. Raise will still be static though.

You will have to call kernel.Get though.

public class DomainEvents
{
    public static IEventHandlerFactory EventHandlerFactory { get; set; }

    public DomainEvents(IEventHandlerFactory factory)
    {
         EventHandlerFactory = factory;
    }

    public static void Raise<T>(T domainEvent) 
    {
        EventHandlerFactory
            .GetDomainEventHandlersFor(event)
            .ForEach(h => h.Handle(event));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM