mercredi 16 septembre 2020

GenericFactory and CRUD form C# WPF [duplicate]

I would like to implement a generic "CRUD" form in WPF. To do so, I created a generic and simple asset factory as follow:

 public class AssetFactory<T>
{
    public virtual T CreateNewAsset()
    {
        return default(T);
    }
    public virtual List<T> DeleteAsset(int assetId)
    {
        return null;
    }
    public virtual List<T> GetAllAssets()
    {
        return null;
    }
}

And here is the concrete implementation, using a CustomerOrder:

public class CustomerOrderFactory : AssetFactory<LightWeight.CustomerOrder>
{
    public override LightWeight.CustomerOrder CreateNewAsset()
    {
            return new LightWeight.CustomerOrder() {Id = result.Id };           
    }

    public override List<LightWeight.CustomerOrder> DeleteAsset(int assetId)
    {
        return GetAllAssets();
    }

    public override List<LightWeight.CustomerOrder> GetAllAssets()
    {
            return assets;
    }
}

I deliberetly removed the code inside each method as it is not relevant to my problem.

Now in my CRUD Window, I have the following code:

public partial class CRUD : Window
{
    private object _factory = null;
    private Type _assetType = null;
    private List<Models.LightWeight.ItemState> _states = null;

    public CRUD()
    {
        InitializeComponent();
    }

    public void LoadAssets<T>(List<T> entitySet, AssetFactory<T> factory)
    {
        _assetType = entitySet.GetType().GetGenericArguments().Single();
        _factory = factory;

        LoadAssetFactory(_assetType);
        LoadStateList(_assetType);
        AssetGrid.ItemsSource = entitySet;
    }
    private void LoadAssetFactory(Type assetType)
    {
        switch (assetType.Name)
        {
            case "CustomerOrder":
                _factory = new CustomerOrderFactory();
                break;
            case "Unit":
                break;
            case "MaterialUnit":
                break;
            case "Process":
                break;
            default:
                break;
        }
    }
    private void LoadStateList(Type assetType)
    {
        switch (assetType.Name)
        {
            case "CustomerOrder":
                CustomerOrderService myService = new CustomerOrderService();
                _states = myService.GetOrderStates();
                break;
            case "Unit":
                break;
            case "MaterialUnit":
                break;
            case "Process":
                break;
            default:
                break;
        }
    }
    private void AddButton_Click(object sender, RoutedEventArgs e)
    {
        if(_factory != null)
        {
            var newAsset = ((AssetFactory<BaseLightWeight>)_factory).CreateNewAsset();
        }
    }

Where BaseLightWeight is a base class to every other asset. My issue is, my concrete factory, in this case CustomerOrderFactory could not be cast to AssetFactory throwing a System.InvalidCastException. While debugging I can see my _factory being "CustomerOrderFactory".

What should I do? Is there some flaw in my logic?

Thanks in advance,

Aucun commentaire:

Enregistrer un commentaire