Skip to content

Tutorial 1: Step 5: Replacing EntityFramework with CQRS.NET object deletes

cdmdotnet edited this page Jun 22, 2017 · 1 revision

Tutorial 1 Step 4

If you missed it, this is the second step, following on from step 4.

Add CQRS.NET commands, events and handlers

  1. Add a new class for OrderDeleted as follows:

// C#

namespace KendoUI.Northwind.Dashboard.Code.Events
{
	using System;
	using System.Collections.Generic;
	using System.Runtime.Serialization;
	using Cqrs.Events;

	public class OrderDeleted : IEvent<string>
	{
		#region Implementation of IEvent

		[DataMember]
		public Guid Id
		{
			get
			{
				return Rsn;
			}
			set
			{
				Rsn = value;
			}
		}

		[DataMember]
		public int Version { get; set; }

		[DataMember]
		public DateTimeOffset TimeStamp { get; set; }

		#endregion

		#region Implementation of IMessageWithAuthenticationToken<string>

		public string AuthenticationToken { get; set; }

		#endregion

		#region Implementation of IMessage

		public Guid CorrelationId { get; set; }

		/// <summary>
		/// The originating framework this message was sent from.
		/// </summary>
		public string OriginatingFramework { get; set; }

		/// <summary>
		/// The frameworks this <see cref="T:Cqrs.Messages.IMessage"/> has been delivered to/sent via already.
		/// </summary>
		public IEnumerable<string> Frameworks { get; set; }

		#endregion

		[DataMember]
		public Guid Rsn { get; set; }

		public OrderDeleted(Guid rsn)
		{
			Rsn = rsn;
		}
	}
}
  1. Add an Delete method to the Order class you created in Step 3.3 as follows:

// C#

	/// <summary>
	/// Logically delete an existing Order
	/// </summary>
	public virtual void DeleteOrder()
	{
		ApplyChange(new OrderDeleted(Rsn));
	}
  1. Add a new class DeleteOrderCommand as follows:

// C#

namespace KendoUI.Northwind.Dashboard.Code.Commands
{
	using System;
	using System.Collections.Generic;
	using System.Runtime.Serialization;
	using Cqrs.Commands;
	using Cqrs.Entities;
	using Models;

	/// <summary>
	/// A <see cref="ICommand{TAuthenticationToken}"/> that requests an existing order gets deleted.
	/// </summary>
	public class DeleteOrderCommand : ICommand<string>
	{
		#region Implementation of ICommand

		[DataMember]
		public Guid Id
		{
			get { return Rsn; }
			set { Rsn = value; }
		}

		[DataMember]
		public int ExpectedVersion { get; set; }

		#endregion

		#region Implementation of IMessageWithAuthenticationToken<string>

		[DataMember]
		public string AuthenticationToken { get; set; }

		#endregion

		#region Implementation of IMessage

		[DataMember]
		public Guid CorrelationId { get; set; }

		/// <summary>
		/// The originating framework this message was sent from.
		/// </summary>
		public string OriginatingFramework { get; set; }

		/// <summary>
		/// The frameworks this <see cref="T:Cqrs.Messages.IMessage"/> has been delivered to/sent via already.
		/// </summary>
		public IEnumerable<string> Frameworks { get; set; }

		#endregion

		[DataMember]
		public Guid Rsn { get; set; }

		public DeleteOrderCommand()
		{
		}

		public DeleteOrderCommand(Guid rsn)
		{
			Rsn = rsn;
		}

		/// <summary>
		/// Explicit cast of <see cref="OrderViewModel"/> to <see cref="DeleteOrderCommand"/>
		/// </summary>
		/// <param name="order">A <see cref="OrderViewModel"/> <see cref="Entity"/> to convert</param>
		/// <returns>A <see cref="CreateOrderCommand"/> object</returns>
		public static explicit operator DeleteOrderCommand(OrderViewModel order)
		{
			var result = new DeleteOrderCommand(order.Rsn);

			return result;
		}
	}
}
  1. Add a new class DeleteOrderCommandHandler as follows:

// C#

namespace KendoUI.Northwind.Dashboard.Code.Commands.Handlers
{
	using Cqrs.Domain;
	using Cqrs.Commands;

	/// <summary>
	/// Responds to any <see cref="DeleteOrderCommand"/>, loads the existing <see cref="Order"/> instance and passes the contents of the <see cref="DeleteOrderCommand"/> to it.
	/// </summary>
	public class DeleteOrderCommandHandler
	
		: ICommandHandler<string, DeleteOrderCommand>
	{
		protected IUnitOfWork<string> UnitOfWork { get; private set; }

		public DeleteOrderCommandHandler(IUnitOfWork<string> unitOfWork)
		{
			UnitOfWork = unitOfWork;
		}

		#region Implementation of ICommandHandler<in DeleteOrderCommand>

		public void Handle(DeleteOrderCommand command)
		{
			// As this is a request to delete an existing order, load the existing order (which will automatically add it to the UnitOfWork)
			Order item = UnitOfWork.Get<Order>(command.Rsn);
			// Request the Order be deleted
			item.DeleteOrder();
			// Commit your changes and publish any events
			UnitOfWork.Commit();
		}

		#endregion
	}
}
  1. Add a new class OrderDeletedEventHandler as follows:

// C#

namespace KendoUI.Northwind.Dashboard.Code.Events.Handlers
{
	using cdmdotnet.AutoMapper;
	using Cqrs.Events;
	using Entities;
	using Repositories;

	public class OrderDeletedEventHandler : IEventHandler<string, OrderDeleted>
	{
		protected IAutomapHelper AutomapHelper { get; private set; }

		protected IOrderRepository OrderRepository { get; private set; }

		public OrderDeletedEventHandler(IAutomapHelper automapHelper, IOrderRepository repository)
		{
			AutomapHelper = automapHelper;
			OrderRepository = repository;
		}

		#region Implementation of IEventHandler<in OrderDeleted>

		public void Handle(OrderDeleted @event)
		{
			// As this is an update of an existing order, load the existing order
			OrderEntity entity = OrderRepository.Load(@event.Rsn);
			// Mark the order as deleted, but leave it in the database, this way we can produce a report of deleted order that can be undeleted.
			entity.IsLogicallyDeleted = true;

			// As this is an update (logical delete) of an existing order, pass the updated entity to the Repository to be updated and persisted
			OrderRepository.Update(entity);
		}

		#endregion
	}
}
  1. Modify the Orders_Destroy method in the OrdersController class as follows:

// C#

	public ActionResult Orders_Destroy([DataSourceRequest]DataSourceRequest request, [ModelBinder(typeof(NullableGuidBinder))]OrderViewModel order)
	{
		if (ModelState.IsValid)
		{
			// Cast the view model into an delete command, and publish the command, waiting for an OrderDeleted event
			// The Telerik Northwind dashboard website is synchronous not asynchronous.
			var command = (DeleteOrderCommand)order;
			CommandPublisher.PublishAndWait<DeleteOrderCommand, OrderDeleted>(command);
		}
		return Json(new[] { order }.ToDataSourceResult(request, ModelState));
	}
  1. Compile and run the site.
  2. Navigate to PRODUCTS & ORDERS
  3. Click the Delete button that is now visible at the end of a row in the order grid.
Clone this wiki locally