Dependency injection Windows服务上的Akka.NET DI&;最佳做法

Dependency injection Windows服务上的Akka.NET DI&;最佳做法,dependency-injection,windows-services,ninject,akka.net,Dependency Injection,Windows Services,Ninject,Akka.net,我试图将Windows服务的一部分迁移到AKKA.net actor模型中,但是当涉及到actor的DI时(它们有一些依赖项,如数据访问层等),我遇到了一点问题,因为我不完全理解如何在服务中连接DependencyResolver。如果这是一个web应用程序,那么它将依赖于HttpConfigurationon的Resolver,但是在这种情况下,我目前有标准内核来进行引导,并获得顶级接口实现来启动Windows服务 我有两个问题: 在windows服务中为参与者配置DI的方法是什么 从另一个

我试图将Windows服务的一部分迁移到AKKA.net actor模型中,但是当涉及到actor的DI时(它们有一些依赖项,如数据访问层等),我遇到了一点问题,因为我不完全理解如何在服务中连接DependencyResolver。如果这是一个web应用程序,那么它将依赖于HttpConfigurationon的Resolver,但是在这种情况下,我目前有标准内核来进行引导,并获得顶级接口实现来启动Windows服务

我有两个问题:

  • 在windows服务中为参与者配置DI的方法是什么
  • 从另一个类中获取系统参与者的最佳方法是什么
我在这里读到:


提前谢谢

我会在启动流程的actor系统后立即配置DI。这是我能提供的最好的,因为我还没有在windows服务的上下文中使用Akka

如果您需要其他类来访问actor系统,以便能够创建顶级actor,那么可以将actorsystem实例本身注册为
IActorRefFactory
,从而访问
ActorOf()
ActorSelection()
方法。显然,作为一个单一的例子,这里不是短暂的寿命

如果您的意思是希望解析系统参与者而不是actorsystem,即在其他类中解析系统参与者,我不确定这是否可行。我对Akka.net中DI的有限理解是,您无法注册和解析活动参与者,因为这在参与者生命周期方面不起作用,您只能注册启动新参与者所需的依赖项。因此,我倾向于在注册容器时手动启动顶级演员,并通过DI启动他们的所有孩子

如果您有非参与者的独立类,并且需要有一个进入actorsystem的访问点,我建议您如上所述注册
IActorRefFactory
,并根据需要创建这些参与者


这是我在自己的项目中遇到的一个问题,因此我欢迎任何其他建议更好方法的答案。

我在windows服务中使用Akka.NET(使用topshelf和autofac,但这种方法适用于任何服务运行者和IoC框架)。我在服务的启动方法中启动顶级参与者,如下所示:

_scope.Resolve<ActorSystem>().ActorOf<MyTopLevelActor>().Tell(new StartMySystemMessage());
为了注册演员系统本身,我正在这样做:

containerBuilder.Register(c =>
{
    var system = ActorSystem.Create("MyActorSystem");
    // ReSharper disable once ObjectCreationAsStatement
    new AutoFacDependencyResolver(lazyContainer.Value, system);
    return system;
}).As<ActorSystem>().SingleInstance();

要从另一个依赖注入类中获取actor系统,您只需将ActorSystem传递给该类的构造函数。我不确定能否在我的应用程序代码中获得对system actor的引用-我自己不需要这样做。

嗨,Steve,非常感谢。我是用你的技巧和扩展方法得到的。目前我正在使用Ninject,但解决方案非常相似。不过,我的用例是有一个系统参与者(IActorRefFactory)的依赖项,我将该依赖项注入到将使用它的第一个非参与者类中。然后从那里我需要得到“顶级演员”,我将通过它,得到第一个演员,并通过我的“开始信息”。从这个参与者那里,我可以访问上下文,然后我可以使用您的扩展方法解析dicator。这有意义吗?谢谢!你好,卡洛斯,太好了,我很高兴这有帮助。是的,你的场景对我来说是有意义的-我在顶层注入了一个具体的ActorSystem,因为它使我的场景中的事情稍微简单一些,但是注入一个IActorRefFactory也可以工作。
var actorWithDependencies = Context.ActorOfDI<ChildActorType>();
    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);
    }
containerBuilder.RegisterAssemblyTypes(typeof(SomeActorType).Assembly).Where(x => x.Name.EndsWith("Actor"));
containerBuilder.Register(c =>
{
    var system = ActorSystem.Create("MyActorSystem");
    // ReSharper disable once ObjectCreationAsStatement
    new AutoFacDependencyResolver(lazyContainer.Value, system);
    return system;
}).As<ActorSystem>().SingleInstance();
Lazy<IContainer> // this is an autofac type
containerBuilder.Build() // this is an autofac call