Windows服务上的Akka.NET DI&最佳实践

时间:2016-02-04 16:00:50

标签: dependency-injection windows-services ninject akka.net

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

我会有两个问题:

  • 为Windows服务中的演员配置DI的方式是什么?
  • 从另一个班级中获取系统角色的最佳方法是什么?

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

提前致谢!

2 个答案:

答案 0 :(得分:4)

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

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

就actor的IoC配置而言,我正在注册包含actor的程序集中的所有actor类型(使用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

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

答案 1 :(得分:0)

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

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

如果您的意思是要解析系统角色而不是演员系统,即其他类中的/system演员,我不确定这是否可行。我对Akka.net中对DI的理解有限,就是你无法注册和解决现场演员,因为这对于演员生命周期没有任何作用,你只能注册启动新演员所需的依赖关系。因此,我倾向于手动启动我的顶层演员,以便通过DI注册我的容器和所有孩子的时间。

如果你有孤立的课程,这些课程不是演员,并且需要有一个访问点进入演员系统,我建议如上所述注册IActorRefFactory并根据需要创建这些演员。

这是我在自己的项目中遇到的一个方括号圆孔问题,所以我欢迎任何其他提出更好方法的答案。