3

フレームワークによって自動生成されるEntity Framework(v5.0)DbContextが呼び出されEntitiesています(私のデザインパターンはデータベースファーストだと思います)。

アプリケーション全体で呼び出しているこの検索コマンド (以下のスニペットに示されています) があります。コントローラーのコードを DRY して、これをメソッド呼び出しにリファクタリングしたいと考えています。

using (var db = new Entities())
{
    DateTime now = DateTime.Today;
    var activeEvents = db.Events.Where(
        b => !b.removed &&
        b.start_date <= now &&
        b.end_date >= now
    );
}

リファクタリング後の例。

using (var db = new Entities())
{
    var activeEvents = db.Events.GetActive();
    // Or maybe it looks like db.GetActiveEvents();
    // I assume this is dictated by best practice
}

これを達成するにはどうすればよいでしょうか?ベストプラクティスと見なされるものは何ですか?

4

2 に答える 2

2

私はおそらくサービスのアプローチを取るでしょう。次の 3 つの主要コンポーネントでサイトを構築します。

  • プレゼンテーション層
    これは MVC Web サイトです (ただし、モバイル サイトやアプリケーションなど、何でもかまいません)。
  • サービス層
    これは、プレゼンテーション層とデータ層の間の呼び出しを処理し、ビジネス ロジックまたはその他の必要なチェックサムを適用します (プレゼンテーション層から遠ざけます)。
  • データ層
    ここにあなたのEntities存在とデータベースへのコンテキストがあります。

簡単にするために、これを 1 つのプロジェクトに保持することができますが、これが大きなアプリケーションになる場合は、別のライブラリにリファクタリングすることをお勧めします。

さて、状況をリファクタリングする方法に関しては、そこにサービス層を追加します後で簡単にテストできるように、インターフェースを使用するのが好きIWhateverServiceです。単体テストに行くときに「ダミー」を実装できますが、実際のアプリケーションを実行するときは現在の実装を維持します。次に、データとやり取りして必要なものを返す (または必要なアクションを実行する [CRUD]) ためのインターフェイスを実装します。例えば

public interface IEventService
{
    IEnumerable<Event> GetActive();
}

public class EventService : IEventService
{
    private readonly Entities entities;
    public EventService(Entities entities)
    {
        this.entities = entities;
    }
    public IEnumerable<Event> GetActive()
    {
        DateTime now = DateTime.Today;
        return this.entities.Events
            .Where(x => !x.removed)
            .Where(x => x.start_date <= now && x.end_date >= now)
            .AsEnumerable();
    }
}

これでサービスができたので、それをコントローラーに接続できます。

public class EventsController : Controller
{
    private readonly IEventService eventService;

    public EventsService()
    {
        this.eventsService = new EventsService(new Entities());
    }

    // action that gets and views the active events
    public ActionResult Active()
    {
        var activeEvents = this.eventsService.Getactive();
        return View(activeEvents);
    }
}

プロジェクトが進化するにつれて、IEventServiceCRUD 操作で更新できます (前述のように)。

public interface IEventService
{
    IEnumerable<Event> All { get; }

    void AddOrUpdateEvent(Event event);
    IEnumerable<Event> GetActive();
    void RemoveEvent(Event event);
}

もちろんEventService、それを に接続し、最終的に 内でアクセスできるようにしますEventsController

[いくつかの]ステップをさらに進めるには、依存性注入を調べて、ビルド方法を(1回)指定しIEventsService、必要に応じて、コントローラーのコンストラクターに引数として渡します(そのように):

public OtherController : Controller
{
    private readonly IUserService;
    private IEventService eventService;

    public OtherController(IUserService userService, IEventService eventService)
    {
        this.userService = userService;
        this.eventService = eventService;
    }

    /* actions */
}

次に、Castle Windsor、ninject、またはこれらのインターフェイスへの単一のマップを含むその他のソリューションのようなものを使用し、(魔法のように) それらをコントローラーのコンストラクターに提供して使用することができます。例を挙げると、Castlewindsor の構成は次のとおりです。

container.Register(
    Component.For<IEventService>().ImplementedBy<EventService>()
        .LifestyleSingleton()
);

IEventServiceこれは基本的に、私が供給を必要とするたびにEventService.

于 2013-07-26T14:50:03.347 に答える
1

これを達成するために部分クラスを使用できるかもしれません。

インターフェース:

interface IMethods<T>
{
    IEnumerable<T> ActiveItems();
}

部分クラス:

partial class Event :IMethods<Event>
{
    public IEnumerable<Event> ActiveItems()
    {
        try
        {
            using (var db = new Entities())
            {
                DateTime now = DateTime.Today;
                return db.Events.Where(b => !b.removed && b.start_date <= now && b.end_date >= now);
            }
        }
        catch (Exception)
        {
            return null;
        }

    }
}

試験方法:

 public class TestClass
{
    public void MyTest()
    {
        var ativevnts = new Event().ActiveItems();
    }
}
于 2013-07-26T13:55:38.877 に答える