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<>
ます。