Я работаю с Аккой. net. Я хочу использовать DryIo c в качестве Io C -контейнера, но в Akka нет готовых адаптеров для актерской системы. В документации сказано, что для использования пользовательского контейнера Io C мне нужно реализовать IDependencyResolver
. В качестве примера я искал библиотеки для AutoFa c и CastleWindsor. Я сделал DependencyResolver для DryIo c:
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Runtime.CompilerServices;
using Akka.Actor;
using Akka.DI.Core;
using DryIoc;
namespace Akka.DI.DryIoc
{
public sealed class DryIocDependencyResolver : IDependencyResolver, INoSerializationVerificationNeeded
{
private readonly IContainer container;
private readonly ConcurrentDictionary<string, Type> typeCache;
private readonly ActorSystem system;
private readonly ConditionalWeakTable<ActorBase, IResolverContext> references;
public DryIocDependencyResolver(IContainer container, ActorSystem system)
{
this.container = container
?? throw new ArgumentNullException("container");
this.system = system
?? throw new ArgumentNullException("system");
this.typeCache = new ConcurrentDictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
this.references = new ConditionalWeakTable<ActorBase, IResolverContext>();
this.system.AddDependencyResolver(this);
}
public Func<ActorBase> CreateActorFactory(Type actorType)
=> () =>
{
var context = this.container.OpenScope();
var key = (ActorBase)context.Resolve(actorType);
this.references.Add(key, context);
return key;
};
public Type GetType(string actorName)
{
var type = actorName.GetTypeValue();
if (type is null)
type = this.container.GetServiceRegistrations()
.Where(registration =>
registration.ImplementationType.Name.Equals(actorName, StringComparison.OrdinalIgnoreCase))
.Select(registration =>
registration.ImplementationType)
.FirstOrDefault();
this.typeCache.TryAdd(actorName, type);
return this.typeCache[actorName];
}
public Props Create<TActor>()
where TActor : ActorBase
=> this.Create(typeof(TActor));
public Props Create(Type actorType)
=> this.system.GetExtension<DIExt>().Props(actorType);
public void Release(ActorBase actor)
{
if (!this.references.TryGetValue(actor, out IResolverContext lifetimeScope))
return;
lifetimeScope.Dispose();
this.references.Remove(actor);
}
}
}
Однако я не уверен, что все сделано правильно. Я особенно сомневаюсь в необходимости использования кэша типов и реализации метода GetType.