NHibernate + ASP.Net MVC +用户活动源

时间:2010-02-04 02:09:19

标签: c# asp.net-mvc nhibernate domain-driven-design user-activity

我正在寻找在社交网站上处理用户活动Feed的最合适方式。目前,我有几项活动可以出现在新闻Feed上,例如:

  • 用户加入网站
  • 用户对帖子的评论
  • 用户在收藏夹中添加帖子
  • 用户向网站添加新帖子

以下是我的域对象的简化版本:

public abstract class NewsItem : Entity, ITenantSpecific  
{  

    public virtual Account Account { get; set; }  
    public virtual DateTime DateTime { get; set; }  

    // returns formatted news html string which gets 
    // overridden by inherted classes  
    public abstract string GetNewsHtml();  
}


public class NewsItemJoiner : NewsItem
{  
    public virtual Account AccountJoined { get; set; }

    public override string GetNewsHtml()
    {
        return "XXX has just joined our music network";
    }
}

正如您所看到的那样,我有一个必须在每个名为GetNewsHtml的活动上覆盖的属性。这并不理想,因为我不相信我的域应该负责生成我的HTML。

我考虑过为每种活动类型使用部分视图,并将NewsItem基类传递给正确的类型。

但是我愿意接受建议。

1 个答案:

答案 0 :(得分:0)

我有类似的问题,但订单类型不同。我决定在视图层(web / controllers)定义渲染,而不是域。你可以这样做:

public interface IRenderer<T> where T: NewsItem 
{
   string Render(T item);
}

public class NewsItemJoinerRenderer: IRenderer<NewsItemJoiner>
{
   public string Render(T item)
   {
       return "XXX has just joined our music network";
   }
}

public class NewsRendererFactory
{
   public IRenderer<T> GetRenderer<T>()
   {
        return ServiceLocator.GetInstance<IRenderer<T>>();
   }
}

然后你可以将NewsRendererFactory传递给控制器​​。也许有一种方法可以避免使用ServiceLocator,但现在我无法分辨。

请注意,如果需要,这可以使您的架构既可配置又可插拔。

您可以定义其他与渲染相关的接口,向IRenderer添加更多属性 - 例如,PartialName等,或者在IRenderer上使用lambda过滤器,Factory使用它来确定此接口实现是否适用于传递的(到GetRenderer( “某种条件”))条件。很多事情都是可能的。

如果您不想要IoC容器(ServiceLocator),可以使用NewsRendererFactory.GetRenderer中的简单switch()语句完成其工作。这将隔离单工厂方法中的逻辑,一旦准备就绪,您将能够使用真正的IoC轻松替换它。

更新:如何获得渲染器。

如果您不使用IoC,则执行类似

的操作
 typeof(IRenderer<>).Assembly.GetTypes().Where(x =>
        x.IsGenericType &&
        x.GetGenericTypeDefinition() == typeof(IRenderer<>) &&
        x.GetGenericArguments().FirstOrDefault() == requestedTypeArguments)

如果可以处理多个渲染器,则可以选择SingleOrDefault()或ToList()。