工厂创建相同界面的不同对象 [英] Factory to create different objects of same interface

查看:69
本文介绍了工厂创建相同界面的不同对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有1个接口:

public interface ISummary
{
   int EventId {get; set;}
}

还有许多实现此接口的具体类:

And many concrete classes that implement this interface:

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;}
}

等...。

唯一的共享属性是 EventId 。有没有一种方法可以创建所有这些摘要对象的工厂方法?我想要1个入口点来决定要创建的对象。

The only shared property is the EventId. Is there a way to have 1 factory method that creates all of these summary objects? I want 1 entry point which decides which objects to create.

所以,像这样:

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
}

我希望在其中进行所有调用其他类调用此方法,而不是自己创建对象。

I want all calls within other classes to call this method rather than creating the objects themselves.

我苦苦挣扎的部分是如何将属性分配给对象的方法传递给此 CreateSummary 方法因为对象上的所有属性都不同?

The part I am struggling with is how do I pass the properties to assign to the objects to this CreateSummary method since all the properties on the objects will be different?

如果有更好的设计模式,我现在很愿意更改对象。

I am open to changing the objects at this point at well if there is a better design pattern I should be using here.

推荐答案

好吧,这就是工厂方法存在的模式:

Well, that's exactly why Factory Method pattern exists :

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;
    }
}

现在您可以使用此工厂:

And now you can use this factory :

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));

这篇关于工厂创建相同界面的不同对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆