0

ソーシャル ネットワーキング サイトでユーザー アクティビティ フィードを処理する最も適切な方法を探しています。現在、次のようなニュースフィードに表示できるいくつかのアクティビティがあります。

  • ユーザーがサイトに参加する
  • 投稿に対するユーザーのコメント
  • ユーザーが投稿をお気に入りに追加する
  • ユーザーがサイトに新しい投稿を追加します

現時点での私のドメインオブジェクトの簡略版は次のとおりです。

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し、正しいタイプにダウンキャストされた基本クラスをそこに渡すことを考えました。

しかし、私は提案を受け入れています。

4

1 に答える 1

0

同様の問題がありますが、注文タイプが異なります。ドメインではなく、ビューレイヤー(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>>();
   }
}

次に、NewsRendererFactoryをコントローラーに渡すことができます。おそらくServiceLocatorを回避する方法はありますが、今のところわかりません。

これにより、アーキテクチャが構成可能になり、必要に応じてプラグイン可能になることに注意してください。

追加のレンダリング関連インターフェイスを定義したり、IRendererにプロパティを追加したり(PartialNameなど)、このインターフェイス実装が渡された(GetRenderer( "some-状態"))状態。多くのことが可能です。

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()を選択できます。

于 2010-02-08T20:43:21.453 に答える