mam*_*esh 5 c# design-patterns factory-pattern
我有1个界面:
public interface ISummary
{
int EventId {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
许多实现此接口的具体类:
public class EmployeeSummary : ISummary
{
public int EventId {get; set;},
public int TotalUniqueCount {get; set;}
public int Location {get; set;}
}
public class CarSummary : ISummary
{
public int EventId {get; set;}
public int TotalMiles {get; set;}
public int TotalHours {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
等等....
唯一的共享属性是EventId.有没有办法让1个工厂方法创建所有这些摘要对象?我想要1个入口点来决定要创建哪些对象.
所以类似于:
public ISummary CreateSummary(ConcreteObjectType with properties)
{
if EmployeeSummary
--Call this method to create and return EmployeeSummary
if CarSummary
--Call this method create and return CarSummary
}
Run Code Online (Sandbox Code Playgroud)
我希望其他类中的所有调用都调用此方法,而不是自己创建对象.
我正在努力的部分是如何传递属性以将对象分配给此CreateSummary方法,因为对象上的所有属性都将不同?
如果我应该在这里使用更好的设计模式,我愿意在这一点上改变对象.
那么,这正是Factory Method模式存在的原因:
public class SummaryFactory
{
// new instance with values assigned by action delegate or default
public T Create<T>(Action<T> action = null) where T : ISummary, new()
{
var result = new T();
action?.Invoke(result);
return result;
}
// with object to assign value from (map)
public T Create<T>(object map) where T : ISummary, new()
{
var result = new T();
PropertyInfo[] props = map.GetType().GetProperties();
PropertyInfo[] tProps = typeof(T).GetProperties();
foreach (var prop in props)
{
var upperPropName = prop.Name.ToUpper();
var foundProperty = tProps.FirstOrDefault(p => p.Name.ToUpper() == upperPropName);
foundProperty?.SetValue(result, prop.GetValue(map));
}
return result;
}
// new instance without generic parameters
public object Create(Type type)
{
var instance = Activator.CreateInstance(type);
// add some other logic that changes instance
return instance;
}
}
Run Code Online (Sandbox Code Playgroud)
现在你可以使用这个工厂了:
var factory = new SummaryFactory();
var carSummary = factory.Create<CarSummary>();
var carSummary2 = factory.Create<CarSummary>(car => { car.TotalMiles = 50; });
var carSummary3 = factory.Create<CarSummary>(new { TotalMiles = 50 });
var employeeSummary = factory.Create(typeof(EmployeeSummary));
Run Code Online (Sandbox Code Playgroud)