C# NHibernate+;ASP.NETMVC+;用户活动提要
我正在寻找最合适的方式来处理我的社交网站上的用户活动提要。目前,我有几个活动可以出现在新闻提要上,例如:C# NHibernate+;ASP.NETMVC+;用户活动提要,c#,asp.net-mvc,nhibernate,domain-driven-design,user-activity,C#,Asp.net Mvc,Nhibernate,Domain Driven Design,User Activity,我正在寻找最合适的方式来处理我的社交网站上的用户活动提要。目前,我有几个活动可以出现在新闻提要上,例如: 用户加入该网站 用户对帖子的评论 用户将帖子添加到收藏夹中 用户向站点添加新帖子 以下是目前我的域对象的简化版本: public abstract class NewsItem : Entity, ITenantSpecific { public virtual Account Account { get; set; } public virtual Dat
- 用户加入该网站
- 用户对帖子的评论
- 用户将帖子添加到收藏夹中
- 用户向站点添加新帖子
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
基类传递给它
不过,我愿意接受建议。我有一个类似的问题,但订单类型不同。我决定在视图层(web/控制器)而不是域中定义渲染。您可以这样做:
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>>();
}
}
公共接口iRender,其中T:NewsItem
{
字符串渲染(T项);
}
公共类NewsItemJoinerRenderer:IRenderer
{
公共字符串呈现(T项)
{
return“XXX刚刚加入我们的音乐网络”;
}
}
公共类新闻渲染器工厂
{
公共iRenderGetRenderer()
{
返回ServiceLocator.GetInstance();
}
}
然后您可以将NewsRenderFactory传递给控制器。也许有一种方法可以避免ServiceLocator,但目前我无法确定
请注意,这使您的体系结构在需要时既可配置又可插入
您可以定义其他与渲染相关的接口,向IRenderer添加更多属性(例如PartialName等),或者在IRenderer上使用lambda筛选器,Factory使用该筛选器确定此接口实现是否适用于传递的(to GetRenderer(“某些条件”))条件。很多事情都是可能的
如果不需要IoC容器(ServiceLocator),可以在NewsRenderFactory.GetRenderer中使用简单的switch()语句完成它的工作。这将隔离单工厂方法中的逻辑,一旦准备好,您就可以轻松地用真正的IoC替换它
更新:如何获取渲染器
如果你不使用IoC,你可以这样做
typeof(IRenderer<>).Assembly.GetTypes().Where(x =>
x.IsGenericType &&
x.GetGenericTypeDefinition() == typeof(IRenderer<>) &&
x.GetGenericArguments().FirstOrDefault() == requestedTypeArguments)
typeof(iRender).Assembly.GetTypes().Where(x=>
x、 IsGenericType&&
x、 GetGenericTypeDefinition()==typeof(iRender)&&
x、 GetGenericArguments().FirstOrDefault()==requestedTypeArguments)
如果可以处理多个渲染器,则可以选择SingleOrDefault()或ToList()。谢谢您的回答。听起来正是我需要做的,并将我的显示器的责任向下传递到控制器级别。谢谢我正在尝试启动并运行它,但是当我有一个不同类型的新闻项目列表(如加入者、状态更新等)时,我正在努力解决如何调用GetRenderer的问题。你有解决这个问题的办法吗?我已经补充了一个答案,说明在没有国际奥委会的情况下如何做到这一点。与国际奥委会相关的答案在不同的容器(温莎等)中有所不同,所以我不能给出一个通用的答案。对于手动实现,一个简单的缓存可以加快解决方案的速度。您好,请原谅我在这里说得不好,但我对泛型相当陌生,您提供的代码似乎只返回iRender接口,而不是每个具体的类,如NewsJoinerRenderer:IRenderer。我还假设“requestedTypeArguments”应该是我想要的新闻项的类型…比如typeof(NewsItemJoiner)?