c# - Akka.net DI - How to inject two actors thru DI? -
what trying pass 2 actors (mummy actor , daddy actor) kid actor. it's best practice use actor reference instead of actor, used iactorref both mummy actor , daddy actor injected thru di named parameter. getting "mummyactor not unique" error. idea how solve it?
using system; using system.threading.tasks; using akka.actor; using akka.di.autofac; using akka.di.core; using autofac; using autofac.core; namespace akka.di.autofac.exampleconsole { public class daddyactor : receiveactor { public daddyactor() { receive<doneeatingmessage>(m => { console.writeline("kid finished eating. what? ~ dad"); }); } } public class mummyactor : receiveactor { public mummyactor() { receive<doneeatingmessage>(m => { console.writeline("kid finished eating. time clean up! ~mummy"); }); } } public class kidactor : receiveactor { private iservice _service; private iactorref _mummyactor; private iactorref _daddyactor; public kidactor(iservice service, iactorref mummyactor, iactorref daddyactor) { this._service = service; this._mummyactor = mummyactor; this._daddyactor = daddyactor; receive<eatmessage>(m=>{ var food = service.getfood(); console.writeline("kid eat food {0}", food); _mummyactor.tell(new doneeatingmessage()); }); } } public class eatmessage{ } public class doneeatingmessage { } public interface iservice { string getfood(); } public class foodservice : iservice { public string getfood() { return "banana"; } } class program { static actorsystem _actorsystem; static void main(string[] args) { var builder = new autofac.containerbuilder(); builder.registertype<foodservice>().as<iservice>(); builder.registertype<mummyactor>().instanceperdependency(); builder.registertype<daddyactor>().instanceperdependency(); builder.register(c => _actorsystem.actorof(_actorsystem.di().props<daddyactor>(), "daddyactor")) .named<iactorref>("daddyactorref") .asself(); builder.register(c => _actorsystem.actorof(_actorsystem.di().props<mummyactor>(), "mummyactor")) .named<iactorref>("mummyactorref") .asself(); builder.registertype<kidactor>() .withparameter( new resolvedparameter( (pi, ctx) => pi.parametertype == typeof(mummyactor), (pi, ctx) => ctx.resolvenamed<iactorref>("mummyactorref") ) ) .withparameter( new resolvedparameter( (pi, ctx) => pi.parametertype == typeof(daddyactor), (pi, ctx) => ctx.resolvenamed<iactorref>("daddyactorref") ) ) .instanceperdependency(); var container = builder.build(); _actorsystem = actorsystem.create("actordisystem"); var propsresolver = new autofacdependencyresolver(container, _actorsystem); var kidactorprops = _actorsystem.di().props<kidactor>(); var kidactor = _actorsystem.actorof(kidactorprops, "kidactor"); kidactor.tell(new eatmessage()); console.writeline("holah"); console.readline(); } } }
the thing mummyactor , daddyactor types not instances of iactorref. cannot use these types when creating kidactor.
i not familiar autofac, able make work this:
builder.registertype<kidactor>() .withparameter( new resolvedparameter( (pi, ctx) => pi.name == "mummyactor", (pi, ctx) => ctx.resolvenamed<iactorref>("mummyactorref") ) ) .withparameter( new resolvedparameter( (pi, ctx) => pi.name == "daddyactor", (pi, ctx) => ctx.resolvenamed<iactorref>("daddyactorref") ) ) .instanceperdependency();
i used name of parameter check. yet think solution can quite dangerous, if rename parameters.
one other thing can delegating creation of these instances service/factory specific methods, , service injected through di.
here got after bit of refactoring:
public class daddyactor : receiveactor { public daddyactor() { receive<doneeatingmessage>(m => { console.writeline("kid finished eating. what? ~ dad"); }); } } public class mummyactor : receiveactor { public mummyactor() { receive<doneeatingmessage>(m => { console.writeline("kid finished eating. time clean up! ~mummy"); }); } } public class kidactor : receiveactor { private iservice _service; private iactorref _mummyactor; private iactorref _daddyactor; public kidactor(iservice service, iparentfactory parentfactory) { this._service = service; this._mummyactor = parentfactory.createmother(context.system); this._daddyactor = parentfactory.createfather(context.system); receive<eatmessage>(m => { var food = service.getfood(); console.writeline("kid eat food {0}", food); _mummyactor.tell(new doneeatingmessage()); _daddyactor.tell(new doneeatingmessage()); }); } } public class eatmessage { } public class doneeatingmessage { } public interface iservice { string getfood(); } public class foodservice : iservice { public string getfood() { return "banana"; } } public interface iparentfactory { iactorref createmother(actorsystem actorsystem); iactorref createfather(actorsystem actorsystem); } public class parentfactory : iparentfactory { public iactorref createfather(actorsystem actorsystem) { return actorsystem.actorof(actorsystem.di().props<daddyactor>(), "daddyactor"); } public iactorref createmother(actorsystem actorsystem) { return actorsystem.actorof(actorsystem.di().props<mummyactor>(), "mummyactor"); } } class program { static actorsystem _actorsystem; static void main(string[] args) { var builder = new autofac.containerbuilder(); builder.registertype<foodservice>().as<iservice>(); builder.registertype<parentfactory>().as<iparentfactory>(); builder.registertype<mummyactor>().instanceperdependency(); builder.registertype<daddyactor>().instanceperdependency(); builder.registertype<kidactor>().instanceperdependency(); var container = builder.build(); _actorsystem = actorsystem.create("actordisystem"); var propsresolver = new autofacdependencyresolver(container, _actorsystem); var kidactorprops = _actorsystem.di().props<kidactor>(); var kidactor = _actorsystem.actorof(kidactorprops, "kidactor"); kidactor.tell(new eatmessage()); console.writeline("holah"); console.readline(); _actorsystem.awaittermination(); } }
i hope you.
Comments
Post a Comment