Akka.NET DI 关于 Windows 服务和最佳实践

Akka.NET DI on Windows Services & Best Practices

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

我会有两个问题:

我一直在阅读这里:http://getakka.net/docs/Dependency%20injection#ninject

提前致谢!

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

如果您需要其他 类 能够访问角色系统以便能够创建 Toplevel 角色,您可以将角色系统实例本身注册为 IActorRefFactory,这样您就可以访问ActorOf()ActorSelection() 方法。显然这里是单个实例,而不是短暂的生命周期。

如果你的意思是你想解析 system actor 而不是 actorsystem,即 /system actor in other 类,我不是确定这是可能的。我在 Akka.net 中对 DI 的有限理解是你不能注册和解析实时演员,因为这对演员生命周期不起作用,你只能注册启动新演员所需的依赖项。因此,我倾向于在注册我的容器时手动启动我的顶级 actor,并通过 DI children

如果您隔离了 类 不是演员并且需要有进入演员系统的访问点,我建议您如上所述注册 IActorRefFactory 并根据需要创建这些演员。

这是我在自己的项目中遇到的一个 square-peg-round-hole 问题,所以我欢迎提出更好方法的任何其他答案。

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

_scope.Resolve<ActorSystem>().ActorOf<MyTopLevelActor>().Tell(new StartMySystemMessage());

从那里我创建儿童演员

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);
    }

就演员的 IoC 配置而言,我在包含演员的程序集中注册了所有演员类型(使用 Autofac),如下所示:

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();

其中 lazyContainer 是:

Lazy<IContainer> // this is an autofac type

并且构造函数委托调用

containerBuilder.Build() // this is an autofac call

要从另一个注入的依赖项 class 中获取 actor 系统,您只需将 ActorSystem 传递到 class 的构造函数中即可。我不确定在我的应用程序代码中获取对系统参与者的引用 - 我自己不需要这样做。