RSS

Tag Archives: type

Autofac Keyed Service Example

Note: Tested on Autofac 4.9.2.

Autofac Keyed Services provide convenience way to register multiple types of same interface with key identifier, see the documentation here.

It’s very useful feature when we want to choose between different implementations of same interface. See below for example:

`WebApiConfig.cs`
This is where we register our type in Autofac container.

var builder = new ContainerBuilder();

builder.RegisterType<CorporateService>()
    .As<IService>()
    .Keyed<IService>("Corporate");
builder.RegisterType<SchoolService>()
    .As<IService>()
    .Keyed<IService>("School");

GlobalContainer.Container = builder.Build();

`GlobalContainer.cs`
This is global object to store our container for resolving type later in application lifecycle.

using Autofac;

namespace QC
{
    public class GlobalContainer
    {
        public static IContainer Container { get; set; }
    }
}

`IService.cs`
This is sample service interface – don’t copy, make your own.

namespace QC.Service
{
    public interface IService
    {
        double GetRate();
    }
}

`CorporateService.cs`
This is sample service interface implementation – don’t copy, make your own.

namespace QC.Service
{
    public class CorporateService : IService
    {
        public double GetRate()
        {
            return 15;
        }
    }
}

`SchoolService.cs`
This is sample service interface implementation – don’t copy, make your own.

namespace QC.Service
{
    public class SchoolService : IService
    {
        public double GetRate()
        {
            return 10;
        }
    }
}

There are 2 options to resolve `IService` to type we desired (ie: Corporate or School).

1. Resolving Explicitly.
Documentation.

`CustomerController.cs`
Sample controller that choose which service to initiate.

using Autofac;
using QC.Service;
using System.Web.Http;

namespace QC.Controllers
{
    public class CustomerController : ApiController
    {
        [HttpGet]
        public IHttpActionResult GetRate()
        {
            // In real-world, we would have business logic to determine which service to initiate
            var service = GlobalContainer.Container.ResolveKeyed<IService>("Corporate");

            var rate = service.GetRate();
            return this.Ok(rate); // Return 15
        }
    }
}

2. Resolving with an Index (recommended).
Documentation.

`CustomerController.cs`

using Autofac.Features.Indexed;
using QC.Service;
using System.Web.Http;

namespace QC.Controllers
{
    public class CustomerController : ApiController
    {
        private readonly IIndex<string, IService> serviceIndexes;
        private readonly IService service;

        public CustomerController(IIndex<string, IService> serviceIndexes)
        {
            this.serviceIndexes = serviceIndexes;

            // In real-world, we would have business logic to determine which service to initiate
            this.service = this.serviceIndexes["Corporate"];
        }

        [HttpGet]
        public IHttpActionResult GetRate()
        {
            var rate = this.service.GetRate();
            return this.Ok(rate); // Return 15
        }
    }
}
Advertisements
 
Leave a comment

Posted by on April 1, 2019 in General

 

Tags: , , , , , ,

Unit Testing DTO Classes

Reason why I unit test my DTO (Data Transfer Object) classes are because I pass these classes to client app and client app might use them and expect certain properties in response. Sometimes I change DTO properties that I used in client app and forget to refactor client app.
By unit testing my DTO classes, it acts as reminder for me to refactor client app whenever DTO properties (or its name) changes.

For example, I have Person DTO.

Person.cs

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Age { get; set; }
}

To unit test, I would create PersonMirror DTO.

public class PersonMirror
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Age { get; set; }
}

Then use following helper class to unit test my DTO.

public class TestHelper
{
    public static void CompareType()
    {
        var errorMessage = "Type: {0}; Property: {1}";

        var instance = Activator.CreateInstance(typeof(T));
        var instanceType = instance.GetType();
        var mirror = Activator.CreateInstance(typeof(TMirror));
        var mirrorType = mirror.GetType();
        var mirrorProperties = mirrorType.GetProperties();

        // Remove 'Mirror' convention
        var mirrorTypeName = mirrorType.Name;
        if (mirrorType.Name.IndexOf("Mirror") > 0)
        {
            mirrorTypeName = mirrorType.Name.Substring(0, mirrorType.Name.IndexOf("Mirror"));
        }

        // Compare type name
        Assert.AreEqual(mirrorTypeName, instanceType.Name);

        // Compare properties
        foreach (var mirrorProperty in mirrorProperties)
        {
            var instanceProperty = instanceType.GetProperty(mirrorProperty.Name);

            Assert.IsNotNull(instanceProperty, string.Format(errorMessage, instanceType.FullName, mirrorProperty.Name));
        }
    }
}

Usage (using MS Test):
PersonTest.cs

[TestClass]
public class PersonTest
{
    [TestMethod]
    public void TestPersonDto()
    {
        TestHelper.CompareType<Person, PersonMirror>();
    }    
}
 
Leave a comment

Posted by on January 18, 2019 in General

 

Tags: , , , , ,

What is HashSet Type?

  • It’s a collection, kind of like Array.
  • Store in form of object’s hash.
  • Unordered.
  • Has standard collection methods: Add, Remove, Contains.
  • Faster in term of performance, compare to List.
  • No access by index. Thus, most┬ámethods take in <T> as parameter.

Reference: MSDN

 
Leave a comment

Posted by on March 6, 2015 in General

 

Tags: ,

 
%d bloggers like this: