我正在尝试将 Windows 服务的一部分迁移到 AKKA.net 参与者模型中,但是当涉及到参与者的 DI 时(他们有一些依赖项,例如数据访问层等)我有一点一个问题,因为我不完全理解如何在服务中连接 DependencyResolver。如果那是一个 Web 应用程序,那么它将是 HttpConfiguraiton 的 DependencyResolver,但是在这种情况下,我目前有标准内核来进行引导并获得顶级接口(interface)实现来启动 Windows 服务。
我会有两个问题:
- 在windows服务中为actor配置DI的方法是什么?
- 从另一个类中获取系统参与者的最佳方法是什么?
我一直在这里阅读:http://getakka.net/docs/Dependency%20injection#ninject
提前致谢!
最佳答案
我在 Windows 服务中使用 Akka.NET(使用 topshelf 和 autofac,但这种方法适用于任何服务运行器和 IoC 框架)。我在服务的启动方法中启动顶级参与者,如下所示:
_scope.Resolve<ActorSystem>().ActorOf<MyTopLevelActor>().Tell(new StartMySystemMessage());
从那里我创建 child Actor
var actorWithoutDependencies = Context.ActorOf<ChildActorType>();
actor 类型有一个默认的构造函数,或者
var actorWithDependencies = Context.ActorOfDI<ChildActorType>();
其中子 actor 类型具有依赖性。
ActorOfDI 调用是我用来在 akka.net 中包装 ActorSystem.DI() 和 IActorContext.DI() 方法的扩展方法,如下所示:
public static IActorRef ActorOfDI<T>(this ActorSystem actorSystem, string name = null) where T : ActorBase
{
return actorSystem.ActorOf(actorSystem.DI().Props<T>(), name);
}
public static IActorRef ActorOfDI<T>(this IActorContext actorContext, string name = null) where T : ActorBase
{
return actorContext.ActorOf(actorContext.DI().Props<T>(), name);
}
就 Actor 的 IoC 配置而言,我在包含 Actor 的程序集中注册所有 Actor 类型(使用 Autofac),如下所示:
containerBuilder.RegisterAssemblyTypes(typeof(SomeActorType).Assembly).Where(x => x.Name.EndsWith("Actor"));
为了注册 Actor 系统本身,我正在这样做:
containerBuilder.Register(c =>
{
var system = ActorSystem.Create("MyActorSystem");
// ReSharper disable once ObjectCreationAsStatement
new AutoFacDependencyResolver(lazyContainer.Value, system);
return system;
}).As<ActorSystem>().SingleInstance();
lazyContainer 是:
Lazy<IContainer> // this is an autofac type
和构造函数委托(delegate)调用
containerBuilder.Build() // this is an autofac call
要从另一个依赖注入(inject)类中获取 actor 系统,您只需将 ActorSystem 传递到该类的构造函数中即可。我不确定在我的应用程序代码中获取对系统参与者的引用 - 我自己不需要这样做。
关于dependency-injection - Windows 服务和最佳实践上的 Akka.NET DI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35205726/