|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
IOC conceptsI'm thinking about fairly common problem - service binding. I'd like to have access to common services from all over the code without any special attenction. The .NET's service provider architecture achieves this, but has one drawback - given service is configured once for whole system; my analysis shows that i have to bind services, depending on who is requesting. Below there are four solutions, but none of them satisfies me. All of them assume there is "wise" class called ServiceManager which is able to resolve references and handle the context tracking - probably solution used in Log4Net (loggers defined by name and assigned after caller type name analysis) would be sufficient for my purposes. The problem i'm trying to aim here is the "client side" code. So - let's start with Log4Net approach: /* Idea 0 */ public class ServiceByDirectReferenceBinding { public void do() { LogService.GetLogService(this).Log("doing"); DaoService.GetDaoService(this).TestConnection(); } } #region Static service access wrappers... public class LogService { static ILogService GetLogService(object caller) { return ServiceManager.Get(typeof(ILogService), caller) } } public class DaoService { static IDaoService GetDaoService(object caller) { return ServiceManager.Get(typeof(IDaoService), caller) } } //for real life sample - see Log4Net api... //the static service access methods could have been //avoided, but then client code would require //direct service manager calls and type casts upon //every service method call (what binds client //code directly to service manager - and it would be //good to avoid it...) #endregion /* Idea 1 */ public class ServiceByProperties { #region "This could have been generated" private ILogService logger; private ILogService Logger { get { if(logger!=null) return logger; logger=ServiceManager.Get(typeof(ILogService),this); return logger; } } private IDaoService dao; private IDaoService Dao { get { if(dao!=null) return dao; dao=ServiceManager.Get(typeof(IDaoService),this); return dao; } } #endregion public void do() { //and such "client" api is my target :) Logger.Log("doing..."); Dao.TestConntection(); } } /* Idea 2 */ public class ServiceByInjection { private ILogService Logger; private IDaoService Dao; public ServiceByInjection() { ServiceManager.InjectDependencies(this); //or ensure dependencies are injected //by caller, what is easy for services resolved using //service manager (dependencies injected during //ServiceManager.Get()), but not possible for //plain objects created with usual o=new O() } public void do() { Logger.Log("doing..."); Dao.TestConntection(); } } /* Idea 3 */ public class ServiceByMagic { public void do() { Logger.Log("doing..."); Dao.TestConntection(); } } #region This could have been generated public static class Logger: implements statically interface ILogService { static void Log(string message) { ServiceManager.Get(typeof(ILogService), FindOutWhoCalledMe()).Log(message); } ... } public static class Dao: implements statically interface IDaoService { static bool TestConntection() { return ServiceManager.Get(typeof(IDaoService), FindOutWhoCalledMe()); } ... } #endregion At the moment it seems Idea 3 would be really nice if it's possible to generate wrapper classes and implement FindOutWhoCalledMe() somehow... Any ideas how to start? (reflection.emit? compiler services?) -- greetings marcin |
|||||||||||||||||||||||