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
,但这会有点奇怪,因为我在抽象工厂中使用抽象工厂 / strong>即可。
注入容器也会有#4的可能性,但这不是一个好主意,因为引入了服务定位器。
我问自己是否有办法在没有Func<>
的情况下使用抽象工厂?
答案 0 :(得分:1)
我不会称之为Abstract Factory,它看起来像是有些人称之为简单工厂的功能。
我建议你看看Mark Seemann的post about abstract factories,他以简单的方式解释了几个选项。
实际上,您可以在ExecuterFactory
中调用您的容器以解决您的依赖关系,以防它与您的组合根位于同一个项目中,或者自己实例化它们new
在您的手动编码工厂中。我更喜欢手动方法,因为我喜欢将容器的使用保持在最低限度的想法。