使用状态构造函数参数在Akka .NET中的依赖注入

时间:2016-07-10 18:21:31

标签: c# dependency-injection akka.net

在构造函数中使用类似字符串参数的东西会使依赖注入变得非常混乱。认为:

public class CurrencyActor
{
    public CurrencyActor(string currency, IRepository repository)
    {
...

还有其他问题(例如this one)来解决依赖注入的这个特殊问题。通常,这可以通过重新思考设计和重构来解决。

但是,如果一个对象的多个版本分别负责不同的数据(例如每种货币的CurrencyActor),那该怎么办?当使用像Akka .NET这样的actor模型时,这是很正常的,但即使在该域之外也是有意义的。

在传递他们需要的初始状态时,使用依赖注入创建这些多个实例的最佳方法是什么?

1 个答案:

答案 0 :(得分:10)

在构造函数中具有依赖性并不是很混乱,它非常常见。这没有什么不妥。

您可以在CurrencyActor上创建一个默认的props静态方法,该方法接收您的依赖项:

public static Props CreateProps(string currency, Irepository repo)
    {
        return Props.Create(() => new CurrrncyActor(currency, repo));
    }

然后创建任意多个:

var usCurrency = system.ActorOf(CurrencyActor.CreateProps("US", someRepo), "US");
var swedishCurrency = system.ActorOf(CurrencyActor.CreateProps("SEK", someRepo), "SEK");

[更新]

关于在Akka中使用DI容器,这被列为否。人们在使用akka.net时犯下的前7个错误中的2个

https://petabridge.com/blog/top-7-akkadotnet-stumbling-blocks/

  

因此,对于参与者来说,管理自己的依赖关系被认为是一种很好的做法,而不是将该工作委托给DI框架。

所以基本上不做。如果你必须,根据那篇文章,Autofac是最好的选择

[更新2]

如果你想动态创建同一个Actor的新实例但是改变一些初始状态,那么你可以让一个负责创建它们的Supervisor:

public class MatchesSupervisor : ReceiveActor
{
    List<IActorRef> _matches = new List<IActorRef>();
    public void MatchesSupervisor()
    {
        Receive<SomeCommandToStartANewMatch>(msg =>
        {
            // store the currently active matches somewhere, maybe on a FullTime message they would get removed?
            _matches.Add(Context.ActorOf(MatchActor.Create(msg.SomeMatchId)));
        }
    }
}

在上面的示例中,没有使用DI容器,并且如果每个MatchActor都需要其他东西,比如IRepository,那么这将在创建时传递到MatchesSupervisor,然后在它们出现时传递给每个MatchActor。创建。

它还有点取决于状态来自何处,以及启动新比赛的机制是什么 - 我只是假设其他一些Actor正在发送消息。

(我在ipad上打字,所以上面的代码可能实际上没有编译,但希望你能得到这个想法,我也遗漏了MatchActor的一个实现,但它只是一个Actor,它传递了一些值它的构造函数)

希望这有帮助!