【发布时间】:2012-04-26 09:03:52
【问题描述】:
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,我不知道如何实现它,如您所见。我可以再次在ExecuterFactory 的构造函数中使用Func,但这有点奇怪,因为我在抽象工厂 中使用了抽象工厂。
还有 #4 的可能性来注入容器,但这不是一个好主意,因为引入了服务定位器。
我问自己有没有办法在没有Func<>的情况下使用抽象工厂?
【问题讨论】:
标签: c# dependency-injection inversion-of-control structuremap abstract-factory