using System; using System.Data; using ServiceStack.CacheAccess; using ServiceStack.Messaging; using ServiceStack.OrmLite; using ServiceStack.Redis; using ServiceStack.ServiceHost; using ServiceStack.WebHost.Endpoints; namespace ServiceStack.ServiceInterface { /// /// Generic + Useful IService base class /// public class Service : IService, IRequiresRequestContext, IServiceBase, IDisposable { public IRequestContext RequestContext { get; set; } private IResolver resolver; public virtual IResolver GetResolver() { return resolver ?? EndpointHost.AppHost; } public virtual IAppHost GetAppHost() { return (resolver as IAppHost) ?? EndpointHost.AppHost; } public virtual Service SetResolver(IResolver resolver) { this.resolver = resolver; return this; } [Obsolete("Use SetResolver")] public virtual Service SetAppHost(IAppHost appHost) { this.resolver = appHost; return this; } public virtual T TryResolve() { return this.GetResolver() == null ? default(T) : this.GetResolver().TryResolve(); } public virtual T ResolveService() { var service = TryResolve(); var requiresContext = service as IRequiresRequestContext; if (requiresContext != null) { requiresContext.RequestContext = this.RequestContext; } return service; } private IHttpRequest request; protected virtual IHttpRequest Request { get { return request ?? (request = RequestContext != null ? RequestContext.Get() : TryResolve()); } } private IHttpResponse response; protected virtual IHttpResponse Response { get { return response ?? (response = RequestContext != null ? RequestContext.Get() : TryResolve()); } } private ICacheClient cache; public virtual ICacheClient Cache { get { return cache ?? (cache = TryResolve()) ?? (cache = (TryResolve() != null ? TryResolve().GetCacheClient() : null)); } } private IDbConnection db; public virtual IDbConnection Db { get { return db ?? (db = TryResolve().Open()); } } private IRedisClient redis; public virtual IRedisClient Redis { get { return redis ?? (redis = TryResolve().GetClient()); } } private IMessageProducer messageProducer; public virtual IMessageProducer MessageProducer { get { return messageProducer ?? (messageProducer = TryResolve().CreateMessageProducer()); } } private ISessionFactory sessionFactory; public virtual ISessionFactory SessionFactory { get { return sessionFactory ?? (sessionFactory = TryResolve()) ?? new SessionFactory(Cache); } } /// /// Dynamic Session Bag /// private ISession session; public virtual ISession Session { get { return session ?? (session = TryResolve() //Easier to mock ?? SessionFactory.GetOrCreateSession(Request, Response)); } } /// /// Typed UserSession /// private object userSession; protected virtual TUserSession SessionAs() { if (userSession == null) { userSession = TryResolve(); //Easier to mock if (userSession == null) userSession = Cache.SessionAs(Request, Response); } return (TUserSession)userSession; } public virtual void PublishMessage(T message) { //TODO: Register In-Memory IMessageFactory by default if (MessageProducer == null) throw new NullReferenceException("No IMessageFactory was registered, cannot PublishMessage"); MessageProducer.Publish(message); } public virtual void Dispose() { if (db != null) db.Dispose(); if (redis != null) redis.Dispose(); if (messageProducer != null) messageProducer.Dispose(); } } }