10.5.09

Giới thiệu StructureMap (phần 1)

StructureMap là một IoC/DI, có thể tải về tại đây.

Mục đích chính của IoC/DI là tạo sự độc lập giữa các thành phần trong lập trình (decouple components from each other).

Ví dụ: bạn có một service là BannerService, và tham số truyền vào khi khởi tạo là BannerRepository, phần constructor như sau:

public BannerService(IRepository<Banner> repository)

{

repository = new BannerRepository();

this.repository = repository;

}

Với cách viết trên, BannerService phụ thuộc vào BannerRepository, điều này gây khó khăn khi refactor code sau này. Chẳng hạn, ta muốn có 2 repository là SqlBannerRepository và InMemoryBannerRepository, như vậy ta phải thay đổi lại tất cả code mà trước đó ta đã khởi tạo BannerRepository.

Để giái quyết khó khăn này, chúng ta thường sử dụng các IoC như StructureMap, Spring.NET, …

Cơ bản về StructureMap dependency injection:

Giả sử chúng ta có 1 interface là IBannerRepository, chúng ta muốn StructureMap trả về đối tượng BannerRepository khi khi có một yêu cầu đối với IbannerRepository

ForRequestedType<IBannerRepository>()

.TheDefaultIsConcreteType<BannerRepository>();

Ta có thể dùng ObjectFactory để lấy về IBannerRepository:

IBannerRepository repository = ObjectFactory.GetInstance<IBannerRepository>();

namespace StructureMapTutorials
{
    class Program
    {
        static void Main(string[] args)
        {
            StructureMapConfiguration
                .ForRequestedType<IBannerRepository>()
                .TheDefaultIsConcreteType<BannerRepository>()
                .CacheBy(InstanceScope.Singleton);
  IBannerRepository bannerRepository = ObjectFactory.GetInstance<IBannerRepository>();
        }
    } 

}

Ví dụ sau mô tả cách StructureMap đẩy (inject) các đối tượng phụ thuộc vào một đối tượng. Giả sử Mỗi Service sẽ có Repository tương ứng như sau:

public class BannerService : IBannerService

{

Private IRepository<Banner> repository;

public BannerService(IRepository<Banner> repository)

{

this.repository = repository;

}

}

Đăng ký trong StructureMap

ForRequestedType<IBannerService>()

.TheDefaultIsConcreteType<BannerService>();

Và khi ta gọi khởi tạo của IBannerService từ ObjectFactory của StructureMap, StructureMap tự động khởi tạo BannerRepository cho đối tượng BannerService

IBannerService svc =
ObjectFactory.GetInstance< IBannerService>();

Hết phần 1 :)

1 comment:

  1. Thanks ! Bài viết ngắn gọn và bổ ích.
    Em thất mấy Projects Open Source nước ngoài sài thằng này rất nhiều. Hi vọng anh có thể dành chút thời gian viết thêm 1 tút nữa cho anh em học hỏi. Cảm ơn nhiều

    ReplyDelete