12

巨大な既存のデータベースからのデータを必要とするMVC3プロジェクトに取り組み始めました。

私の最初のアイデアは、EF 4.1を使用して、必要なテーブルを表すために一連のPOCOを作成することでしたが、一部のテーブルの一部の列のみが必要なため、マッピングが非常に複雑になると思い始めています。 。(コメントで説明してくれたStevenに感謝します。

だから私はMassiveORMを試してみようと思いました。私は通常、作業単位の実装を使用しているため、すべてを適切に分離しておくことができ、依存性注入を使用できます。これは私がMassiveのために持っているものの一部です:

public interface ISession
{
    DynamicModel CreateTable<T>() where T : DynamicModel, new();

    dynamic Single<T>(string where, params object[] args) 
        where T : DynamicModel, new();

    dynamic Single<T>(object key, string columns = "*") 
        where T : DynamicModel, new();

    // Some more methods supported by Massive here
}

そして、これが上記のインターフェースの私の実装です:

public class MassiveSession : ISession
{
    public DynamicModel CreateTable<T>() where T : DynamicModel, new()
    {
        return new T();
    }

    public dynamic Single<T>(string where, params object[] args) 
        where T: DynamicModel, new()
    {
        var table = CreateTable<T>();
        return table.Single(where, args);
    }

    public dynamic Single<T>(object key, string columns = "*") 
        where T: DynamicModel, new()
    {
        var table = CreateTable<T>();
        return table.Single(key, columns);
    }
}

問題は、、First()およびLast()メソッドFindBy()にあります。Massiveは、呼び出されたオブジェクトに基づいており、dynamic上記のメソッドを定義していません。代わりに、オーバーライドされた実装を介してそれらを処理します。DynamicModelTryInvokeMethod()DynamicObject

public override bool TryInvokeMember(InvokeMemberBinder binder, 
    object[] args, out object result) { }

でこれらのメソッドを「インターフェース」する方法に迷っていますISession。、およびISessionのサポートをどのように提供できますか?First()Last()FindBy()

言い換えると、Massiveのすべての機能を使用しながら、クラスをデータアクセスから切り離すにはどうすればよいでしょうか。

4

2 に答える 2

8

この質問に答えられたことは知っていますが、Massiveのすべてのメソッドは仮想としてマークされているため、簡単にモックできます。私はそれを提案するかもしれません。または-気にしないでください。

私は現在MVC3ビデオのプロジェクトでこれを行っており、Railsのプレイブックからページを取得しています-オブジェクトの静的メソッドとしてクエリを提供し、そこから移動します。私は自分のテストをデータベースにヒットさせました-それは物事をまったく遅くせず、すべての機械を取り除くためにかなり自由です。

RailsにはDI/IoCがなく、嬉しいです。

于 2011-06-30T21:21:12.447 に答える
4

インターフェイス

基本的に、ISession の Find、Last、および FindBy の署名には、いくつかのインターフェイスに関するオプションがあります。

bool TryInvoke(InvokeBinder binder, object[] args, out object result)動的引数名で同じ構文を維持したい場合は、First、Last、および Find をすべて getter にして、同じ構文を与えるDynamicObject を実装して動的に返す必要がありdynamic Find(column:val, otherColum:otherVal)ます。大まかな基本的な例を次に示します。

    public class MassiveSession : ISession
{ 

    ...

    public dynamic Find{
           get {
               return new DynamicInvoker(this,name:"Find");
           }
    }

    public class DynamicInvoker : DynamicObject{
        ...
        public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
        {
             ...
             return true;          
        }

    }
}

完全に静的に定義されたメソッドが必要な場合は、 IDictionary の単一のパラメーターを実行するか、キーペアを提供するために何かを行う必要があります。

Massive 動的メソッドへの呼び出しの転送

これにも2つの方法があります。

簡単な方法は、オープン ソース フレームワークのImpromptuInterfaceを使用することです。これにより、C# コンパイラと同様に動的メソッドをプログラムで呼び出すことができます (動的名前付きパラメーターを含む)。

var arg = InvokeArg.Create;
return Impromptu.InvokeMember(table, "Find", arg("column", val),arg("otherColum", otherVal));

TryInvokeMemberまたは、 ;に入るパラメーターを偽造することもできます。

于 2011-06-24T16:39:26.440 に答える