我正在尝试将Windows服务的一部分迁移到AKKA.net actor模型中,但是当涉及到演员的DI(他们有一些依赖项,如数据访问层等)时,我有一点点一个问题,因为我不完全了解如何在服务中连接DependencyResolver。如果那是一个Web应用程序,那么它将是HttpConfiguraiton的DependencyResolver,但是在这种情况下,我目前有标准内核来执行引导并获得顶级接口implementacion来启动Windows服务。
我会有两个问题:
我一直在这里阅读:http://getakka.net/docs/Dependency%20injection#ninject
提前致谢!
答案 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
并根据需要创建这些演员。
这是我在自己的项目中遇到的一个方括号圆孔问题,所以我欢迎任何其他提出更好方法的答案。