3
public interface IExecuter
{
    void Execute();
}

public class Executer : IExecuter
{
    readonly Data _data;
    readonly IService _service;

    public Executer(Data data, IService service)
    {
        _data = data;
        _service = service;
    }

    public void Execute()
    {
        Console.WriteLine("I consume the data object with id {0}", _data.Id);
        _service.DoAnything();
    }
}

public interface IService
{
    void DoAnything();
}

public class Service : IService
{
    public void DoAnything()
    {
        Console.WriteLine("I do anything else");
    }
}

public class Data
{
    public int Id { get; set; }
    public string Description { get; set; }
}

ランタイム値をコンストラクターに渡す必要があるため、IExecuter を作成するための抽象ファクトリが必要です。

可能性 #1 -静的抽象ファクトリを使用する:

public class FormularWindow
{
    public static Func<Data, IExecuter> CreateExecuter = data => {throw new NotImplementedException("");};

    public void InvokeExecuter()
    {
        var selectedData = GetSelectedData();
        var executer = CreateExecuter (selectedData);
        executer.Execute();
    }

    private static Data GetSelectedData()
    {
        return new Data { Id = 4, Description = "Test" };
    }
}

class Program
{
    static void Main()
    {
        ObjectFactory.Initialize(x =>
        {
            x.For<IExecuter>().Use<Executer>();
            x.For<IService>().Use<Service>();
        });
        FormularWindow.CreateExecuter = data => ObjectFactory.With(data.GetType(), data).GetInstance<IExecuter>();

        var consumer = ObjectFactory.GetInstance<FormularWindow>();

        consumer.InvokeExecuter();

        Console.ReadLine();
    }
}

可能性 #2 -抽象ファクトリをコンストラクタ パラメータとして使用します

public class FormularWindow
{
    readonly Func<Data, IExecuter> _createExecuter;

    public FormularWindow(Func<Data, IExecuter> createExecuter)
    {
        _createExecuter = createExecuter;
    }

    public void InvokeExecuter()
    {
        var selectedData = GetSelectedData();
        var executer = _createExecuter(selectedData);
        executer.Execute();
    }

    private static Data GetSelectedData()
    {
        return new Data { Id = 4, Description = "Test" };
    }
}

class Program
{
    static void Main()
    {
        ObjectFactory.Initialize(x =>
        {
            x.For<IExecuter>().Use<Executer>();
            x.For<IService>().Use<Service>();
            x.For<Func<Data, IExecuter>>().Use(data => ObjectFactory.With(data.GetType(), data).GetInstance<IExecuter>());
        });


        var consumer = ObjectFactory.GetInstance<FormularWindow>();

        consumer.InvokeExecuter();

        Console.ReadLine();
    }
}

可能性 #3 - IExecuterFactory を使用します

class Program
{
    static void Main()
    {
        ObjectFactory.Initialize(x =>
        {
            x.For<IExecuter>().Use<Executer>();
            x.For<IService>().Use<Service>();
            x.For<IExecuterFactory>().Use<ExecuterFactory>();
        });

        var consumer = ObjectFactory.GetInstance<FormularWindow>();

        consumer.InvokeExecuter();

        Console.ReadLine();
    }
}

public interface IExecuterFactory
{
    IExecuter Create(Data data);
}

public class ExecuterFactory : IExecuterFactory
{
    readonly IService _service;

    public ExecuterFactory(IService service)
    {
        _service = service;
    }

    public IExecuter Create(Data data)
    {
        return new Executer(data, _service);// ?!
    }
}


public class FormularWindow
{
    readonly IExecuterFactory _executerFactory;


    public FormularWindow(IExecuterFactory executerFactory)
    {
        _executerFactory = executerFactory;
    }

    public void InvokeExecuter()
    {
        var selectedData = GetSelectedData();
        var executer = _executerFactory.Create(selectedData);
        executer.Execute();
    }

    private static Data GetSelectedData()
    {
        return new Data { Id = 4, Description = "Test" };
    }
}

可能性#3では、ご覧のとおり、実装方法がわかりません。Funcのコンストラクターで再び使用できますが、抽象ファクトリー内で抽象ExecuterFactoryファクトリーを使用するため、それは一種の奇妙なことです。

コンテナーを注入する #4 の可能性もありますが、サービス ロケーターを導入するため、それはお勧めできません。

なしで抽象ファクトリを使用する方法があるかどうか自問しFunc<>ます。

4

1 に答える 1

1

私はそれをAbstract Factoryとは呼びません。これは、Simple Factory と呼ばれるものと機能的に同等のように見えます。

Mark Seemann の抽象ファクトリに関する投稿をご覧になることをお勧めします。彼はいくつかのオプションを簡単な方法で説明しています。

実際には、コンテナーがExecuterFactoryコンポジション ルートと同じプロジェクトに存在する場合に依存関係を解決するためにコンテナーを呼び出すかnew、手動でコーディングされたファクトリでコンテナーを自分でインスタンス化することができます。コンテナの使用を最小限に抑えるという考えが好きなので、私は手動のアプローチを好みます。

于 2012-04-26T15:10:12.717 に答える