我有一个基本服务类,我有一堆服务,在服务类上存储数据是好/坏的做法?
例如:
public interface IFunkyService
{
void AddComment(int quoteid, string comment);
void SetProirirty(int quoteid, Importance proirity);
}
public class FunkyService : CustomServiceBase, IFunkyService
{
private readonly IRepo _repo;
private readonly IUserSession _user;
public FunkyService(IRepo repo, IUserSession user)
{
_repo = repo;
_user = user;
}
public void SetProirirty(int quoteid, Important priority)
{
//get quote object then persists
}
public void AddComment(int quoteid, string comment)
{
//get quote object then persists
}
}
我可以简单地使用一个私有方法将引用对象存储在类中吗? e.g。
private Quote _quote {get;set;} //store on the class???
private void GetQuote(int quoteid)
{
_quote = _repo.single(quoteid); //or whatever
}
答案 0 :(得分:2)
请注意,只要服务对象本身,类中的值才会生效。每次向服务发出请求时,都会创建和销毁服务对象,因此Quote
仅在单个请求的长度内生效。我可以看到的唯一目的是每个请求缓存(即,在单个请求期间,您引用Quote
对象五次。您应该只需要从后备存储中查找一次)
FunkyService
类GetQuote
Quote
。FunkyService
对象。Quote
的值不再存储在类中,因为对象已消失。编辑:您希望这样做的原因是,检索引用对象是在一个地方完成的,但不会一遍又一遍地调用(即,多次调用)只需要一个请求到数据库)。您可以实现可缓存属性设计模式,以便在不使用类变量的情况下拥有每个请求缓存。它看起来像这样:
private Dictionary<int, Quote> _quoteCache =
new Dictionary<int, Quote>(); // cache storage - NEVER ACCESS DIRECTLY
public Quote GetQuote(int quoteid)
{
// cache is invalid, so populate
if (!_quoteCache.ContainsKey(quoteid))
{
_quoteCache.Add(quoteid, _repo.single(quoteid));
}
// return back to caller
return _quoteCache[quoteid];
}
在上面的示例中,缓存存储从数据库中检索的每个唯一quoteid。因此,如果您连续五次调用GetQuote(5)
,则只能通过_repo
一次从数据库中检索它。但是,如果您调用GetQuote(6)
,它将再次转到数据库,因为该引用无法从缓存中获得。之后,5和6仍然存储在缓存中,直到服务请求完成并处理完毕。
Edit2:在您提供的示例中:
var t = GetTags(_quote);
// then do something with t, I may pass to another method:
if(IsClosed(_quote)){}
不要引用类变量,而是让您的存储库返回一个Quote
对象并传递该引用,如下所示:
private Quote GetQuote(int quoteid)
{
return _repo.single(quoteid); //or whatever
}
// other code
var q = GetQuote(quoteid); // get the quote once
var t = GetTags(q); // q doesn't have to retrieve from repo again
if (IsClosed(q)) {}
// etc.
答案 1 :(得分:1)
不确定这是否适用于您的情况,但是当将无状态服务(或通常任何组件)切换为有状态时,您需要考虑一些问题:
根据经验,尽量保持代码无状态。使用它更安全,允许您通过执行异步操作来提高性能,我也认为其他人更容易理解它。当您需要保持状态,特别是共享状态时,请确保对它的所有访问都是线程安全的并且记录得非常好。
答案 2 :(得分:0)
在您的服务中处于有状态的问题是需要考虑Service类实例的生命周期。
例如,如果您的服务是通过WCF公开的,那么“每次调用”的默认实例化模式将否定方法调用之间的任何状态,因为每次调用都意味着为来自客户端的每个调用创建一个新的服务实例。但是,您可以使用InstanceContextMode.PerSession在调用之间“保持”客户端和服务之间的连接,这样可以为您提供状态的一些好处,尽管它还有一个缺点,即可扩展性可能受限,因为您的客户端最终现在拥有控制您所在州使用的服务器资源。
@mellamokb的观点很棒,因为SOA中状态的一个常见用途是缓存。