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();
}
}
}