【问题标题】:Getting ninject Kernel in a module with topshelf.ninject使用 topshelf.ninject 在模块中获取 ninject 内核
【发布时间】:2015-10-22 04:33:33
【问题描述】:

我正在编写一项新服务,并且是第一次使用 Topshelf 和 EasyNetQ。我没有使用 MVC 或 WebAPI(大多数 ninject 教程/博客文章似乎都假设)。关键依赖项是 Topshelf、Ninject(mono 构建版本而不是 nugget 包)和 EasyNetQ。

我选择 ninject 是基于在 MVC 项目中使用过它,以及 Topshelf.ninject 库的可用性。

所以在设置 topshelf 时,我调用 UseNinject 方法并传入一个 Ninject 模块:

        public static int Main(string[] args)
    {

        Thread.CurrentThread.Name = "Service Main Thread";


            var exitCode = HostFactory.Run(x =>
            {
                x.UseNinject(new Prototype.Service.Modules.IocModule());

                x.Service<SampleService>(s =>
                {
                    s.ConstructUsingNinject();
                    s.WhenStarted((service, hostControl) => service.Start(hostControl));
                    s.WhenStopped((service, hostControl) => service.Stop(hostControl));
                });
                x.RunAsLocalSystem();
                x.SetDescription("Prototype .NET Micro Service");
                x.SetDisplayName(typeof(SampleService).Namespace);
                x.SetServiceName(typeof(SampleService).Namespace);
                x.UseNLog();
            });
        return (int) exitCode;
        }
    }

模块如下所示:

public class IocModule : NinjectModule
{
    /// <summary>
    /// Bind Interfaces to implimentations for dependancy injection
    /// </summary>
    public override void Load()
    {
        Bind<ISampleService>().To<SampleService>();
        Bind<IAdvancedBus>().ToMethod(context => BusFactory.CreateMessageBus()).InSingletonScope();
        Bind<IExchange>().ToMethod(context => ExchangeFactory.CreatExchange(Kernel.Get<IAdvancedBus>())).InSingletonScope();
        Bind<IQueue>().ToMethod(context => QueueFactory.CreatQueue(Kernel.Get<IAdvancedBus>())).InSingletonScope();
        Bind<ILogger>().To<Logger.Logger>().InSingletonScope();
        Bind<IMessagePublisher>().To<MessagePublisher>();
        Bind<IMessageConsumer>().To<MessageConsumer>();
        Bind<ISubscriber>().To<SampleSubscriber>();
        Bind<IAutoSubscriberMessageDispatcher>().To<MessageDispatcher>();
        Bind(typeof(IRepository<>)).To(typeof(MongoRepository<>));
        Bind<IHostingEnvironment>().To<HostingEnvironment>();
        Bind<ISampleLogic>().To<SampleBusinessLogicClass>();
    }
}

还有一家工厂:

    public static class QueueFactory
{
    public static IQueue CreatQueue(IAdvancedBus bus)
    {
        var queue = bus.QueueDeclare("QueueName");
        return queue;
    }
}

我的问题在于 ninject 模块中 IExchange 和 IQueue 的绑定。如您所见,工厂方法需要一个 IAdvancedBus 实例,但是 Kernel 在运行时为空。我试图通过方法 args 传递依赖项,因为它是一个静态类,我无法通过构造函数注入。

这样做的正确方法是什么?我似乎无法获得对 ninject 内核的引用,而且感觉不对。我觉得我正在尝试以错误的方式做这件事的兔子洞。此外,内核被标记为过时,我看不到另一种获取对象实例的方法。显然我也不能像在 MVC 中那样使用依赖解析器。

topshelf 是否有等效的依赖解析器?有更好的模式吗?我会做一些事情来保持松散耦合,所以我想避免静态类、单例或其他任何迫使我进入难以测试的具体依赖关系的东西。

有什么想法吗?

【问题讨论】:

    标签: dependency-injection ninject topshelf easynetq


    【解决方案1】:

    Ninject.IContext(lambda 中的参数)引用了IKernel,因此更改为:

    Bind<IQueue>().ToMethod(context => QueueFactory.CreatQueue(context.Kernel.Get<IAdvancedBus>())).InSingletonScope();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-26
      • 1970-01-01
      • 2021-04-30
      • 1970-01-01
      • 2014-09-03
      • 2018-08-07
      • 2014-07-15
      相关资源
      最近更新 更多