What's the best way to expose a Model object in a ViewModel?

Posted by Angel on Programmers See other posts from Programmers or by Angel
Published on 2014-06-05T09:14:28Z Indexed on 2014/06/05 15:37 UTC
Read the original article Hit count: 258

In a WPF MVVM application, I exposed my model object into my viewModel by creating an instance of Model class (which cause dependency) into ViewModel. Instead of creating separate VM properties, I wrap the Model properties inside my ViewModel Property.

My model is just an entity framework generated proxy class:

public partial class TblProduct
{
    public TblProduct()
    {
        this.TblPurchaseDetails = new HashSet<TblPurchaseDetail>();
        this.TblPurchaseOrderDetails = new HashSet<TblPurchaseOrderDetail>();
        this.TblSalesInvoiceDetails = new HashSet<TblSalesInvoiceDetail>();
        this.TblSalesOrderDetails = new HashSet<TblSalesOrderDetail>();
    }

    public int ProductId { get; set; }
    public string ProductCode { get; set; }
    public string ProductName { get; set; }
    public int CategoryId { get; set; }
    public string Color { get; set; }
    public Nullable<decimal> PurchaseRate { get; set; }
    public Nullable<decimal> SalesRate { get; set; }
    public string ImagePath { get; set; }
    public bool IsActive { get; set; }

    public virtual TblCompany TblCompany { get; set; }
    public virtual TblProductCategory TblProductCategory { get; set; }
    public virtual TblUser TblUser { get; set; }
    public virtual ICollection<TblPurchaseDetail> TblPurchaseDetails { get; set; }
    public virtual ICollection<TblPurchaseOrderDetail> TblPurchaseOrderDetails { get; set; }
    public virtual ICollection<TblSalesInvoiceDetail> TblSalesInvoiceDetails { get; set; }
    public virtual ICollection<TblSalesOrderDetail> TblSalesOrderDetails { get; set; }
}

Here is my ViewModel:

public class ProductViewModel : WorkspaceViewModel
{
    #region Constructor
    public ProductViewModel()
    {
        StartApp();
    }

    #endregion //Constructor

    #region Properties

    private IProductDataService _dataService;
    public IProductDataService DataService
    {
        get
        {
            if (_dataService == null)
            {
                if (IsInDesignMode)
                {
                    _dataService = new ProductDataServiceMock();
                }
                else
                {
                    _dataService = new ProductDataService();
                }
            }
            return _dataService;
        }

    }

    //Get and set Model object
    private TblProduct _product;
    public TblProduct Product
    {
        get
        {
            return _product ?? (_product = new TblProduct());
        }
        set
        {
            _product = value;
        }
    }

    #region Public Properties

    public int ProductId
    {
        get
        {
            return Product.ProductId;
        }
        set
        {
            if (Product.ProductId == value)
            {
                return;
            }

            Product.ProductId = value;
            RaisePropertyChanged("ProductId");
        }
    }

    public string ProductName
    {
        get
        {
            return Product.ProductName;
        }
        set
        {
            if (Product.ProductName == value)
            {
                return;
            }

            Product.ProductName = value;
            RaisePropertyChanged(() => ProductName);
        }
    }

    private ObservableCollection<TblProduct> _productRecords;
    public ObservableCollection<TblProduct> ProductRecords
    {
        get { return _productRecords; }
        set
        {
            _productRecords = value;
            RaisePropertyChanged("ProductRecords");
        }
    }

    //Selected Product
    private TblProduct _selectedProduct;
    public TblProduct SelectedProduct
    {
        get
        {
            return _selectedProduct;
        }
        set
        {
            _selectedProduct = value;
            if (_selectedProduct != null)
            {
                this.ProductId = _selectedProduct.ProductId;
                this.ProductCode = _selectedProduct.ProductCode;
            }
            RaisePropertyChanged("SelectedProduct");
        }
    }

    #endregion  //Public Properties

    #endregion  // Properties

    #region Commands

    private ICommand _newCommand;
    public ICommand NewCommand
    {
        get
        {
            if (_newCommand == null)
            {
                _newCommand = new RelayCommand(() => ResetAll());
            }
            return _newCommand;
        }
    }

    private ICommand _saveCommand;
    public ICommand SaveCommand
    {
        get
        {
            if (_saveCommand == null)
            {
                _saveCommand = new RelayCommand(() => Save());
            }
            return _saveCommand;
        }
    }

    private ICommand _deleteCommand;
    public ICommand DeleteCommand
    {
        get
        {
            if (_deleteCommand == null)
            {
                _deleteCommand = new RelayCommand(() => Delete());
            }
            return _deleteCommand;
        }
    }

    #endregion //Commands

    #region Methods

    private void StartApp()
    {
        LoadProductCollection();
    }

    private void LoadProductCollection()
    {
        var q = DataService.GetAllProducts();
        this.ProductRecords = new ObservableCollection<TblProduct>(q);
    }


    private void Save()
    {
        if (SelectedOperateMode == OperateModeEnum.OperateMode.New)
        {
              //Pass the Model object into Dataservice for save
              DataService.SaveProduct(this.Product);
        }
        else if (SelectedOperateMode == OperateModeEnum.OperateMode.Edit)
        {
             //Pass the Model object into Dataservice for Update
              DataService.UpdateProduct(this.Product);
        }
        ResetAll();
        LoadProductCollection();
    }


    #endregion  //Methods
}

Here is my Service class:

class ProductDataService:IProductDataService
{
    /// <summary>
    /// Context object of Entity Framework model
    /// </summary>
    private MaizeEntities Context { get; set; }

    public ProductDataService()
    {
        Context = new MaizeEntities();
    }

    public IEnumerable<TblProduct> GetAllProducts()
    {
        using(var context=new R_MaizeEntities())
        {
           var q = from p in context.TblProducts
                   where p.IsDel == false
                   select p;

            return new ObservableCollection<TblProduct>(q);
        }
    }

    public void SaveProduct(TblProduct _product)
    {
        using(var context=new R_MaizeEntities())
        {
            _product.LastModUserId = GlobalObjects.LoggedUserID;
            _product.LastModDttm = DateTime.Now;
            _product.CompanyId = GlobalObjects.CompanyID;
            context.TblProducts.Add(_product);

            context.SaveChanges();
        }
    }

    public void UpdateProduct(TblProduct _product)
    {
        using (var context = new R_MaizeEntities())
        {
            context.TblProducts.Attach(_product);

            context.Entry(_product).State = EntityState.Modified;
            _product.LastModUserId = GlobalObjects.LoggedUserID;
            _product.LastModDttm = DateTime.Now;
            _product.CompanyId = GlobalObjects.CompanyID;
            context.SaveChanges();
        }
    }

    public void DeleteProduct(int _productId)
    {
        using (var context = new R_MaizeEntities())
        {
            var product = (from c in context.TblProducts
                    where c.ProductId == _productId
                    select c).First();

            product.LastModUserId = GlobalObjects.LoggedUserID;
            product.LastModDttm = DateTime.Now;
            product.IsDel = true;
            context.SaveChanges();
        }
    }


}

I exposed my model object in my viewModel by creating an instance of it using new keyword, also I instantiated my DataService class in VM. I know this will cause a strong dependency.

So:

  1. What's the best way to expose a Model object in a ViewModel?
  2. What's the best way to use DataService in VM?

© Programmers or respective owner

Related posts about c#

Related posts about design-patterns