0

データモデルであるサードパーティのクラスがあるとしましょう。おそらく 100 個のプロパティがあります (パブリック セッターとゲッターを持つものもあれば、パブリック ゲッターとプライベート セッターを持つものもあります)。このクラスを ContosoEmployeeModel と呼びましょう

このクラスをインターフェイス (Name プロパティと DBID プロパティを持つ INavigationItem) でファサード化して、アプリケーションで使用できるようにしたいと考えています (これは PowerShell プロバイダーですが、現時点では重要ではありません)。ただし、ContosoEmployeeModel としても使用できる必要があります。

私の最初の実装は次のようになりました。

public class ContosoEmployeeModel
{
    // Note this class is not under my control. I'm supplied
    // an instance of it that I have to work with.

    public DateTime EmployeeDateOfBirth { get; set; }
    // and 99 other properties.
}

public class FacadedEmployeeModel : ContosoEmployeeModel, INavigationItem
{
    private ContosoEmployeeModel model;
    public FacadedEmployeeModel(ContosoEmployeeModel model)
    {
        this.model = model;
    }

    // INavigationItem properties
    string INavigationItem.Name { get; set;}

    int INavigationItem.DBID { get; set;}

    // ContosoEmployeeModel properties
    public DateTime EmployeeDateOfBirth
    {
        get { return this.model.EmployeeDateOfBirth; }
        set { this.model.EmployeeDateOfBirth = value; }
    }
    // And now write 99 more properties that look like this :-(
}

ただし、これには大量の定型コードを記述してすべてのプロパティを公開する必要があることは明らかであり、できればこれは避けたいと思います。このコードを部分クラスで T4 コード生成することができます。他に良いアイデアがない場合はそうしますが C# のちょっとした魔法 使ってもっと良いアイデアがあるかどうかをここで尋ねたいと思います。

注意してください - ContosoEmployeeModel を取得するために使用する API は、ContosoEmployeeModel のみを返すことができます - FacededEmployeeModel を返すように拡張することはできません。そのため、モデルをラップすることが考えられる唯一の解決策です - ただし、修正されてうれしいです: )

4

2 に答える 2

1

別のアプローチとして、AutoMapper を使用して基本クラスをファサードにマップする方法が適している場合があります。サンプル コードは次のとおりです。

class Program
    {
        static void Main(string[] args)
        {
            var model = new Model { Count = 123, Date = DateTime.Now, Name = "Some name" };

            Mapper.CreateMap<Model, FacadeForModel>();
            var mappedObject = AutoMapper.Mapper.Map<FacadeForModel>(model);

            Console.WriteLine(mappedObject);

            Console.ReadLine();
        }

        class Model
        {
            public string Name { get; set; }

            public DateTime Date { get; set; }

            public int Count { get; set; }
        }

        interface INavigationItem
        {
            int Id { get; set; }

            string OtherProp { get; set; }
        }

        class FacadeForModel : Model, INavigationItem
        {
            public int Id { get; set; }

            public string OtherProp { get; set; }
        }
    }
于 2013-07-02T10:01:31.513 に答える
1

Resharper を使用すると、含まれるオブジェクトのインターフェイスを含まれるオブジェクトにコピーし、メソッド呼び出し/プロパティ アクセスを含まれるオブジェクトにトンネリングする「委譲メンバー」を作成できます。

http://www.jetbrains.com/resharper/webhelp/Code_Generation__Delegating_Members.html

これが完了したら、プロキシ クラスでインターフェイスを抽出できます。

于 2013-07-02T10:16:44.677 に答える