public void ProductInfoUpdateEvent_Ctor_Should_Set_Arguments_Correctly()
        {
            Guid     productId = Guid.NewGuid();
            string   eanCode   = "ean";
            string   sku       = "sku";
            string   name      = "name";
            string   url       = "url";
            Currency price     = new Currency {
                Amount = 10, Code = "EUR"
            };
            string   description = "description";
            int      unitInStock = 1;
            bool     isOnSale    = true;
            DateTime?onSaleFrom  = DateTime.Today;
            DateTime?onSaleTo    = DateTime.Today.AddMonths(1);

            var @event = new ProductInfoUpdateEvent(productId, eanCode, sku, name, url, price, description, unitInStock, isOnSale, onSaleFrom, onSaleTo);

            Assert.Equal(productId, @event.ProductId);
            Assert.Equal(eanCode, @event.EanCode);
            Assert.Equal(sku, @event.Sku);
            Assert.Equal(name, @event.Name);
            Assert.Equal(url, @event.Url);
            Assert.Equal(price, @event.Price);
            Assert.Equal(description, @event.Description);
            Assert.Equal(unitInStock, @event.UnitInStock);
            Assert.Equal(isOnSale, @event.IsOnSale);
            Assert.Equal(onSaleFrom, @event.OnSaleFrom);
            Assert.Equal(onSaleTo, @event.OnSaleTo);

            Assert.Equal(productId, @event.AggregateId);
            Assert.Equal(typeof(Catalog.Models.Product), @event.AggregateType);
        }
 /// <summary>
 /// <see cref="IHandleEvent{TEvent}.Handle(TEvent)"/>
 /// </summary>
 /// <param name="event"></param>
 public void Handle(ProductInfoUpdateEvent @event)
 {
     try
     {
         EventStore.Save(@event);
     }
     catch
     {
         throw;
     }
 }
        /// <summary>
        /// Implementation of <see cref="IProductCommands.UpdateProductInfo(Guid, string, string, string, string, Currency, string, int, bool, DateTime?, DateTime?)"/>
        /// </summary>
        /// <param name="productId">The product id</param>
        /// <param name="ean">The EAN code</param>
        /// <param name="sku">The SKU code</param>
        /// <param name="name">The product's name</param>
        /// <param name="url">The product's url</param>
        /// <param name="price">The product's price</param>
        /// <param name="description">The product's description</param>
        /// <param name="unitInStock">The product's unit in stock</param>
        /// <param name="isOnSale">Whether the product is on sale</param>
        /// <param name="onSaleFrom">The date and time of when the product starts to be on sale</param>
        /// <param name="onSaleTo">The date and time till when the product is on sale</param>
        /// <returns></returns>
        public virtual async Task UpdateProductInfo(Guid productId, string ean, string sku, string name, string url, Currency price, string description, int unitInStock, bool isOnSale, DateTime?onSaleFrom, DateTime?onSaleTo)
        {
            try
            {
                if (productId == Guid.Empty)
                {
                    throw new ArgumentException("value cannot be empty", nameof(productId));
                }

                var product = await Repository.GetByKeyAsync <Product>(productId);

                if (product.EanCode != ean)
                {
                    product.ChangeEanCode(ean);
                }

                if (product.Sku != sku)
                {
                    product.ChangeSku(sku);
                }

                if (product.Name != name)
                {
                    product.ChangeName(name);
                }

                if (product.Url != url)
                {
                    product.ChangeUrl(url);
                }

                if (product.Price != price)
                {
                    product.SetPrice(price);
                }

                if (product.Description != description)
                {
                    product.ChangeDescription(description);
                }

                if (product.UnitInStock != unitInStock)
                {
                    product.SetUnitInStock(unitInStock);
                }

                if (product.IsOnSale != isOnSale || product.OnSaleFrom != onSaleFrom || product.OnSaleTo != onSaleTo)
                {
                    if (isOnSale)
                    {
                        if (!onSaleFrom.HasValue && !onSaleTo.HasValue)
                        {
                            product.SetOnSale();
                        }
                        else
                        {
                            product.SetOnSale(onSaleFrom, onSaleTo);
                        }
                    }
                    else
                    {
                        product.RemoveFromSale();
                    }
                }

                await Repository.SaveChangesAsync();

                var @event = new ProductInfoUpdateEvent(productId, ean, sku, name, url, price, description, unitInStock, isOnSale, onSaleFrom, onSaleTo);
                EventBus.RaiseEvent(@event);
            }
            catch
            {
                throw;
            }
        }