我正在写一项新服务,并且是第一次使用Topshelf和EasyNetQ。我没有使用MVC或WebAPI(大多数ninject教程/博客文章似乎都假设)。关键依赖项是Topshelf,Ninject(单声道构建版本而不是块包)和EasyNetQ。
我根据在MVC项目中使用它以及Topshelf.ninject库的可用性选择了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有一个等效的依赖解析器吗?这有更好的模式吗?我做了什么来保持松散耦合的东西,所以我想避免静态类,单例或任何其他迫使我进入难以测试的具体依赖。
任何想法?
答案 0 :(得分:2)
%macro vtype(ds,var);
%local dsid varnum rc vartype;
%let dsid = %sysfunc(open(&ds));
%let varnum = %sysfunc(varnum(&dsid,&var));
%let vartype = %sysfunc(vartype(&dsid,&varnum));
%let rc = %sysfunc(close(&dsid));
&vartype
%mend vtype;
/*Example*/
%put %vtype(emptyset,myvar);
/*Output*/
N
(lambda中的参数)引用Ninject.IContext
,因此更改为:
IKernel