Ehsan Ghanbari

Experience, DotNet, Solutions

Redis as a cache server

Although Redis is much more than a cache, But it's possible to use as cache server especially in distributed applications. Redis lets you operate on the values and it's just a key-value pair in-memory database.

To getting started, get the latest version of Redis from here and install in your windows machine (Server) by instruction and run it in your services. Redis runs in your server machine (you can have Redis server and client in one machine which could be your client development machine) and you call it from a client by a library. Now to work with Redis in a server you need to get stack exchange via Nuget and implement your methods provided by it.

Note: You can read all descriptions and instructions of stack exchange Redis in Github.

public class RedisCacheManager

    {

        private readonly ConnectionMultiplexer _connectionMultiplexer;

        private readonly IDatabase _dataBase;

        private IServer _server;



        private static Lazy<ConfigurationOptions> configurations = new Lazy<ConfigurationOptions>(() =>

        {

            var configuration = new ConfigurationOptions();

            configuration.EndPoints.Add("192.168.110.149:6421");

            configuration.ConnectTimeout = 100000;

            configuration.SyncTimeout = 100000;

            configuration.AllowAdmin = true;

            configuration.Password = "skdfenr4";

            return configuration;

        });



        public RedisCacheManager()

        {

            _connectionMultiplexer = ConnectionMultiplexer.Connect(configurations.Value);

            _dataBase = _connectionMultiplexer.GetDatabase();

            var endpoints = _connectionMultiplexer.GetEndPoints();

            _server = _connectionMultiplexer.GetServer(endpoints.First());

        }



        public object Retrieve(string key)

        {

            var rValue = _dataBase.StringGet(key);

            if (!rValue.HasValue)

                return rValue;

            return JsonHelper.Deserialize<object>(rValue);

        }



        public T Retrieve<T>(string key)

        {

            var rValue = _dataBase.StringGet(key);

            if (!rValue.HasValue)

                return JsonHelper.Deserialize<T>(null);

            return JsonHelper.Deserialize<T>(rValue);

        }



        public T Retrieve<T>(string key, int pageIndex)

        {

            var rValue = _dataBase.StringGet(key);

            if (!rValue.HasValue)

                return JsonHelper.Deserialize<T>(null);

            return JsonHelper.Deserialize<T>(rValue);

        }



        public bool Contain(string key)

        {

            return _dataBase.KeyExists(key);

        }



        public void Store(string key, object value)

        {

            if (value == null)

                return;



            var entryBytes = JsonHelper.Serialize(value);

            _dataBase.StringSet(key, entryBytes);

        }



        public void Store(string key, object value, int cacheTime)

        {

            if (value == null)

                return;



            var entryBytes = JsonHelper.Serialize(value);

            var expiresIn = TimeSpan.FromMinutes(cacheTime);



            _dataBase.StringSet(key, entryBytes, expiresIn);

        }



        public void Remove(string key)

        {

            _dataBase.KeyDelete(key);

        }



        public void Clear()

        {

            var endpoints = _connectionMultiplexer.GetEndPoints(true);

            foreach (var endpoint in endpoints)

            {

                var server = _connectionMultiplexer.GetServer(endpoint);

                server.FlushAllDatabases();

            }

        }



        private static byte[] Serialize(object item)

        {

            var jsonString = JsonConvert.SerializeObject(item);

            return Encoding.UTF8.GetBytes(jsonString);

        }



        private static T Deserialize<T>(byte[] serializedObjectValue)

        {

            if (serializedObjectValue == null)

                return default(T);



            var jsonString = Encoding.UTF8.GetString(serializedObjectValue);

            return JsonConvert.DeserializeObject<T>(jsonString);

        }

    }

 

I Just implemented the most used methods in a caching system, you can implement your own based on your needs. As you see I created configurations with some initializing. for example EndPoints(you can get it from the server that Redis is running on) and password (for making the connection between client and server secure).  In the constructor of the class, you need to connect to Redis server via ConnectionMultiplexer and get the database to work with.



Multithreading in java

I'm not a java developer and I've never worked with java in real products. Sometimes I read and concepts and compare with C#, Java is cool as well! By using multithread you can perform many operations together and the system doesn't block the user until completing the operations. There are two ways for multithreading in java: inhering from a class named Thread and implementing an interface named Runnable. I like Runnable because you have another chance to inherit the class from another class if you would need!

 

public class Multithread implements Runnable  {

    public void run() {

        System.out.println("Thread: " + Thread.currentThread().getId() + " is running");

    }

}

 

class MainClass

{

    public static void main(String[] args)

    {

        int n = 5;

        for (int i=0; i<5; i++)

        {

            Thread object = new Thread(new Multithread());

            object.start();

        }

    }

}

 

If you run this code, the following output will appear:

 

Thread: 8 is running
Thread: 9 is running
Thread: 10 is running
Thread: 11 is running
Thread: 12 is running



Using Generic type for type casting in F#

In order to validate some input of type object into numeric types, you can use System.Convert in F#. We have them in F# as well! Look at the following function:

 

open System

let validate<'a, 'b> (cast: 'a -> 'b) (x: 'a) =
    try
        cast x |> Some
    with _ -> None

let a = validate int "3423"
let d = validate<obj, decimal> Convert.ToDecimal (null :> obj)
let e = validate<string, DateTime> Convert.ToDateTime "2017-10-10"

 

Validate has been used to convert obj to decimal and even to DateTime. In order to see the result of the following piece of code, you can use it in F#.Net Core console application: 

 

[<EntryPoint>]

let main argv =

    printfn "%A" e // or d and a that has calculated by Validate<,>

    0

 



Delayed jobs in Hangfire

Hangfire is a job scheduling framework which provides background processing without needing any windows service. That's the main point and competitive advantage of Hangfire in compare to other similar libraries. Imagine sending a million of message or email in your application, you don't need to force the user to wait for all the processes to be completed. Despite, there are lots of ways to accomplish the mentioned job; Hangfire uses the request processing pipeline of ASP.Net for processing and executing jobs however it runs in every framework of Microsoft!

In order to create delayed jobs, just call the BackgroundJob.Schedule(). Create a console application and install the library from nuget  and call Schedule(,) :

            BackgroundJob.Schedule(

                () => Console.WriteLine("Job Scheduled!"),

                TimeSpan.FromDays(5));

The above code simply will be scheduled the job from 5 days later. You can also run the task in a specific date like this:

   BackgroundJob.Schedule(

             () => Console.WriteLine("Job Scheduled!"),

             new DateTime(2017, 02, 05, 12, 00, 00));

Not that the default time of enqueueing the scheduled jobs by hangfire server is 15 seconds which is changeable. To change that default periodical schedule, initiate the BackgroundJobServerOptions in the constructor:

 var options = new BackgroundJobServerOptions

{

    SchedulePollingInterval = TimeSpan.FromMinutes(5)

};

var server = new BackgroundJobServer(options);

HangFire Server is responsible for background job processing. To start the background processing, create an instance of  BackgroundJobServer and start it.       

        var server = new BackgroundJobServer(options);           

        server.Start();

At the time of writing this post, the start() of BackgroundJobServer() is obsolete! You don't have to call start, it will be started automatically by the constructor. Call dispose() to waiting for server shutdown:

server.Dispose();

 



Simple command handler in .net

 

I want to introduce a simple command handler pattern in order to separate commands and queries of your applications if it’s needed. Sometimes especially in large-scale applications, you need to have two layers for reading and write separated and assign two teams to work on them.

You can use the pattern in this post based on the complexity and needs of your application. I recommend that don’t call this CQRS pattern as it’s something completely different and more complex.

 

Get started and Create an interface with no any member:

public interface ICommand

    {

    }

You will see later in this blog post that ICommand is just a flag to determine the commands for the handler. Every command which is trying to make a change in application’s state should return a result. so create another interface named ICommandResult

public interface ICommandResult

    {

        string Message { get; }

        bool Success { get; }

    }

implement the above interface as CommandResult and derive the FailureResult and SuccessResult classes from:

internal abstract class CommandResult : ICommandResult

    {

        public string Message { get; protected set; }

        public bool Success { get; protected set; }

    }



internal class FailureResult : CommandResult

    {

        public FailureResult(string message)

        {

            Success = false;

            Message = message;

        }

    }



    internal class SuccessResult : CommandResult

    {

        public SuccessResult(string message)

        {

            Success = true;

            Message = message;

        }

    }

Now create an interface for handling the validations in CommandBus class:

internal interface IValidationHandler<in TCommand> where TCommand : ICommand

    {

        IEnumerable<ValidationResult> Validate(TCommand command);

    }

 And create a class for validations:

public class ValidationResult

    {

        /// <summary>

        /// Initializes a new instance of the <see cref="ValidationResult"/> class.

        /// </summary>

        public ValidationResult()

        {

        }



        /// <summary>

        /// Initializes a new instance of the <see cref="ValidationResult"/> class.

        /// </summary>

        /// <param name="memeberName">Name of the memeber.</param>

        /// <param name="message">The message.</param>

        public ValidationResult(string memeberName, string message)

        {

            MemberName = memeberName;

            Message = message;

        }



        /// <summary>

        /// Initializes a new instance of the <see cref="ValidationResult"/> class.

        /// </summary>

        /// <param name="message">The message.</param>

        public ValidationResult(string message)

        {

            Message = message;

        }



        /// <summary>

        /// Gets or sets the name of the member.

        /// </summary>

        /// <value>

        /// The name of the member.  May be null for general validation issues.

        /// </value>

        public string MemberName { get; set; }



        /// <summary>

        /// Gets or sets the message.

        /// </summary>

        /// <value>

        /// The message.

        /// </value>

        public string Message { get; set; }

    }

And now create the most used interface in this pattern. ICommandBus will be called as bus handler in every command:

public interface ICommandBus

    {

        ICommandResult Send<TCommand>(TCommand command) where TCommand : ICommand;

        IEnumerable<ValidationResult> Validate<TCommand>(TCommand command) where TCommand : ICommand;

    }

To implementing this interface, create a class again with the following definition:

  internal class CommandBus : ICommandBus

    {

        public ICommandResult Send<TCommand>(TCommand command) where TCommand : ICommand

        {

            var handler = DependencyResolver.Current.GetService<ICommandHandler<TCommand>>();



            if (!((handler != null) && handler != null))

            {

                throw new CommandHandlerNotFoundException(typeof(TCommand));

            }

            return handler.Execute(command);

        }



        public IEnumerable<ValidationResult> Validate<TCommand>(TCommand command) where TCommand : ICommand

        {

            var handler = DependencyResolver.Current.GetService<IValidationHandler<TCommand>>();

         

            if (!((handler != null) && handler != null))

            {

                throw new ValidationHandlerNotFoundException(typeof(TCommand));

            }

            return handler.Validate(command);

        }

    }

The above class will handle every command received from the bus. And now for executing the handler or so-called for implementing the business, you need an interface:

internal interface ICommandHandler<in TCommand> where TCommand : ICommand

    {

        ICommandResult Execute(TCommand command);

    }

And finally as I’m personally interested in to have my own exception handler, so I create a customized handler:

public class CommandHandlerNotFoundException : Exception

    {

        public CommandHandlerNotFoundException(Type type)

            : base(string.Format("Command handler not found for command type: {0}", type))

        {

        }

    }



    internal class ValidationHandlerNotFoundException : Exception

    {

        public ValidationHandlerNotFoundException(Type type)

            : base(string.Format("Validation handler not found for command type: {0}", type))

        {

        }

    }

Finished! Now let’s use the above codes in a real work application. We are going to handle the products of an e-commerce application as its business is easier to comprehend for everybody:

    public interface IProductCommand : ICommand

    {

        string Name { get; set; }



        string OriginalName { get; set; }



        string Description { get; set; }



        decimal Price { get; set; }

     

    }

  

    public class ProductCommand : IProductCommand

    {

        public string Name { get; set; }



        public string OriginalName { get; set; }



        public string Description { get; set; }



        public decimal Price { get; set; }     

    }



    public class CreateProductCommand : ProductCommand

    {

    }



    public class EditProductCommand : ProductCommand

    {

        public Guid ProductId { get; set; }



        public DateTime CreationDate { get; set; }



        public DateTime LastUpdateDate { get; set; }

    }



public class DeleteProductCommand : ICommand

    {

        public Guid[] ProductIds { get; set; }

    }

You can see that I created an interface derived from ICommand named IProductCommand and finally created the target classes. And at the end we should create the Product handler class:

internal partial class ProductCommandHandler :

        ICommandHandler<CreateProductCommand>,

        ICommandHandler<EditProductCommand>,   

        ICommandHandler<DeleteProductCommand>       

    {

        private readonly IProductRepository _productRepository;

        private readonly IMembershipRepository _membershipRepository;     

        private readonly IUnitOfWork _unitOfWork;

        private readonly ICacheManager _cacheManager;

        private readonly ILogger _logger;



        public ProductCommandHandler(

            IProductRepository productRepository,        

            IUnitOfWork unitOfWork,

            ILogger logger,

            ICacheManager cacheManager)

        {

            _productRepository = productRepository;          

            _unitOfWork = unitOfWork;

            _logger = logger;

            _cacheManager = cacheManager;        

        }

       

        public ICommandResult Execute(CreateProductCommand command)

        {

            try

            {

                if (command == null)

                {

                    throw new ArgumentNullException();

                }



                var product = new Product();

                AddProductAppurtenance(command, product);

                _productRepository.Add(product);

                _unitOfWork.Commit();

                return new SuccessResult(ProductCommandMessage.ProductCreatedSuccessfully);

            }

            catch (Exception exception)

            {

                _logger.Error(exception.Message);

                return new FailureResult(ProductCommandMessage.ProductCreationFailed);

            }

        }



        public ICommandResult Execute(EditProductCommand command)

        {

            try

            {

                if (command == null)

                {

                    throw new ArgumentNullException();

                }



                var product = _productRepository.GetProductDetailById(command.ProductId);

                ClearProductAppurtenance(product);

                AddProductAppurtenance(command, product);

                _productRepository.Edit(product);

                _unitOfWork.Commit();



                return new SuccessResult(ProductCommandMessage.ProductEditedSuccessfully);

            }

            catch (Exception exception)

            {

                _logger.Error(exception.Message);

                return new FailureResult(ProductCommandMessage.ProductEditionFailed);

            }

        }



        public ICommandResult Execute(DeleteProductCommand command)

        {

            if (command.ProductIds == null)

            {

                throw new ArgumentNullException();

            }



            var exceptions = new List<Exception>();

            foreach (var productId in command.ProductIds)

            {

                try

                {

                    var product = DeleteProduct(productId);

                    _productRepository.Edit(product);

                }

                catch (Exception exception)

                {

                    exceptions.Add(exception);

                    return new FailureResult(ProductCommandMessage.ProductDeletionFailed);

                }

            }



            if (exceptions.Any())

            {

                throw new AggregateException(exceptions);

            }



            _unitOfWork.Commit();

            return new SuccessResult(ProductCommandMessage.ProductsDeletedSuccessufully);

        }  

 

We used all of the classes introduced in infrastructure.

Note 1: so you need to have an IOC container tool, to the best of my Knowledge, AsClosedTypesOf in Autofac resolves the ICommandHandler. This a piece of code I wrote for IOC handler:

  public class CommandModule : Module

    {

        protected override void Load(ContainerBuilder builder)

        {

            builder.RegisterModule<RepositoryModule>();

            builder.RegisterType<CommandBus>().As<ICommandBus>().InstancePerRequest();

            builder.RegisterAssemblyTypes(ThisAssembly).AsClosedTypesOf(typeof(ICommandHandler<>)).InstancePerRequest();

        }

    }

Note 2: a penny for your thoughts! how to use ICommandBus!? See the below piece of code as an example:

[HttpPost]

        public JsonResult DeleteProduct(DeleteProductCommand command)

        {

            var result = _commandBus.Send(command);

            return JsonMessage(result);

        }

have fun.



About Me

Ehsan Ghanbari

Hi! my name is Ehsan. I'm a developer, passionate technologist, and fan of clean code. I'm interested in enterprise and large-scale applications architecture and design patterns. I spend a lot of time on software architecture. Since 2008, I've been as a developer for different companies and organizations and I've been focusing on Microsoft ecosystem all the time. During the past years, Read More

Post Tags
Pending Blog Posts
using Elmah in asp.net MVC4
Using FluentSecurity in MVC
Strategic design
Factory Pattern
time out pattern in ajax
Redis as a cache server
How to use PagedList In asp.net MVC
Multiple submit buttons in asp.net MVC
Domain driven design VS model driven architecture
What's the DDD-lite?