Thư viện doanh nghiệp Unity vs các container IoC khác [đã đóng]


135

Những ưu và nhược điểm của việc sử dụng Enterprise Library Unity so với các bộ chứa IoC khác (Windsor, Spring.Net, Autofac ..) là gì?


9
Những loại câu hỏi luôn luôn đóng. Các ý kiến ​​rất quan trọng. Có một nơi để đặt chúng?
Jeson Martajaya

1
@JesonMartajaya, tôi muốn khen ngợi chính xác cùng một nhận xét, thật khó chịu khi các câu hỏi đang bị đóng, nhưng không có câu trả lời cho một sự thay thế.
Mohammed Noureldin

Câu trả lời:


234

Tôi đang chuẩn bị một bài thuyết trình cho một nhóm người dùng. Như vậy tôi vừa trải qua một loạt chúng. Cụ thể: AutoFac, MEF, Ninject, Spring.Net, StructMap, Unity và Windsor.

Tôi muốn thể hiện 90% trường hợp (tiêm constructor, chủ yếu là những gì mọi người sử dụng IOC cho dù sao). Bạn có thể kiểm tra giải pháp tại đây (VS2008)

Như vậy, có một vài khác biệt chính:

  • Khởi tạo
  • Đối tượng truy xuất

Mỗi người trong số họ cũng có các tính năng khác (một số có AOP và gizmos tốt hơn, nhưng nói chung tất cả những gì tôi muốn một IOC làm là tạo và truy xuất các đối tượng cho tôi)

Lưu ý: sự khác biệt giữa truy xuất đối tượng thư viện khác nhau có thể được phủ định bằng cách sử dụng CommonServiceLocator: http://www.codeplex.com/CommonServiceLocator

Điều đó khiến chúng tôi khởi tạo, được thực hiện theo hai cách: thông qua mã hoặc thông qua cấu hình XML (app.config / web.config / custom.config). Một số hỗ trợ cả hai, một số chỉ hỗ trợ một. Tôi nên lưu ý: một số sử dụng các thuộc tính để giúp IoC hoạt động.

Vì vậy, đây là đánh giá của tôi về sự khác biệt:

Ninject

Chỉ khởi tạo mã (có thuộc tính). Tôi hy vọng bạn thích lambdas. Mã khởi tạo trông như thế này:

 IKernel kernel = new StandardKernel(
                new InlineModule(
                    x => x.Bind<ICustomerRepository>().To<CustomerRepository>(),
                    x => x.Bind<ICustomerService>().To<CustomerService>(),
                    x => x.Bind<Form1>().ToSelf()
                    ));

Sơ đồ cấu trúc

Mã khởi tạo hoặc XML hoặc các thuộc tính. v2,5 cũng rất lambda'y. Nói chung, đây là một trong những mục yêu thích của tôi. Một số ý tưởng rất thú vị xung quanh cách StructMap sử dụng các thuộc tính.

ObjectFactory.Initialize(x =>
{
    x.UseDefaultStructureMapConfigFile = false;
    x.ForRequestedType<ICustomerRepository>()
        .TheDefaultIsConcreteType<CustomerRepository>()
        .CacheBy(InstanceScope.Singleton);

    x.ForRequestedType<ICustomerService>()
        .TheDefaultIsConcreteType<CustomerService>()
        .CacheBy(InstanceScope.Singleton);

    x.ForConcreteType<Form1>();
 });

Đoàn kết

Mã khởi tạo và XML. Thư viện đẹp, nhưng cấu hình XML là một nỗi đau ở mông. Thư viện tuyệt vời cho Microsoft hoặc các cửa hàng đường cao tốc. Mã khởi tạo rất dễ dàng:

 container.RegisterType<ICustomerRepository, CustomerRepository>()
          .RegisterType<ICustomerService, CustomerService>();

Mùa xuân.NET

XML chỉ gần như tôi có thể nói. Nhưng đối với chức năng Spring.Net thực hiện mọi thứ dưới ánh mặt trời mà IoC có thể làm. Nhưng vì cách duy nhất để đơn vị hóa là thông qua XML nên các cửa hàng .net thường tránh. Mặc dù, nhiều cửa hàng .net / Java sử dụng Spring.Net vì sự giống nhau giữa phiên bản .net của Spring.Net và dự án Java Spring.

Lưu ý : Hiện tại có thể cấu hình trong mã với việc giới thiệu Spring.NET CodeConfig .

Lâu đài

XML và mã. Giống như Spring.Net, Windsor sẽ làm bất cứ điều gì bạn có thể muốn nó làm. Windsor có lẽ là một trong những container IoC phổ biến nhất xung quanh.

IWindsorContainer container = new WindsorContainer();
container.AddComponentWithLifestyle<ICustomerRepository, CustomerRepository>("CustomerRepository", LifestyleType.Singleton);
container.AddComponentWithLifestyle<ICustomerService, CustomerService>("CustomerService",LifestyleType.Singleton);
container.AddComponent<Form1>("Form1");

Tự động điền

Có thể trộn cả XML và mã (với v1.2). Thư viện IoC đơn giản đẹp. Có vẻ để làm những điều cơ bản với không nhiều phiền phức. Hỗ trợ các container lồng nhau với phạm vi cục bộ của các thành phần và quản lý thời gian sống được xác định rõ.

Đây là cách bạn khởi tạo nó:

var builder = new ContainerBuilder();
builder.Register<CustomerRepository>()
        .As<ICustomerRepository>()
        .ContainerScoped();
builder.Register<CustomerService>()
        .As<ICustomerService>()
        .ContainerScoped();
builder.Register<Form1>();

Nếu tôi phải chọn ngày hôm nay: tôi có thể sẽ đi với StructMap. Nó có sự hỗ trợ tốt nhất cho các tính năng ngôn ngữ C # 3.0 và linh hoạt nhất trong việc khởi tạo.

Lưu ý : Chris Brandsma đã biến câu trả lời ban đầu của mình thành một bài đăng trên blog .


1
Cấu hình Xml chỉ, làm cho nó khó hơn nhiều để cấu hình. Về cơ bản, những người duy nhất mà tôi thấy muốn sử dụng Spring.Net là các nhà phát triển Java trước đây.
Chris Brandma

Chris, liên quan đến kết luận của bạn: bạn có thể vui lòng cung cấp thêm một số chi tiết về a) tính năng C # 3 nào bạn đang đề cập đến và b) loại khởi tạo nào quan trọng đối với bạn không? Cảm ơn!
Nicholas Blumhardt

2
Xin chào Nicholas: đối với hỗ trợ C # 3, mọi thứ mà Autofac đã làm. :) Để khởi tạo, tôi muốn hỗ trợ dễ dàng cho singletons / non singletons và khởi tạo mỗi phiên. Cuối cùng, tôi muốn những cách dễ dàng để tham chiếu theo tên tùy chỉnh. (một cái gì đó là một PITA trong StructMap). Tính năng cuối cùng mà tôi thích hơn bây giờ so với khi tôi viết bản gốc này: AutoMocking. Tôi không sử dụng nó mọi lúc, nhưng thật tuyệt khi có arount.
Chris Brandsma

Bạn cũng đã đề cập đến MEF, tôi sử dụng MEF để phân phối các đối tượng triển khai IRep repository của tôi và thấy nó hoạt động tốt. Suy nghĩ của bạn về MEF là gì?
terjetyl

Đây là một đoạn phim ngắn tuyệt vời kéo dài 20 phút, giới thiệu hầu hết Unity: pnpguidance.net/Screencast/ chủ
Pat

7

Theo như tôi đã thấy thì chúng khá giống nhau, ngoại trừ một vài chi tiết thực hiện ở đây và đó. Ưu điểm lớn nhất mà Unity có được so với đối thủ là nó được cung cấp bởi Microsoft, có rất nhiều công ty ngoài kia sợ OSS.

Một nhược điểm là nó khá mới nên có thể có lỗi mà những người chơi cũ đã sắp xếp.

Đã nói rằng, bạn có thể muốn kiểm tra này .


4

Chủ đề cũ nhưng vì đây là điều đầu tiên mà Google chỉ cho tôi khi tôi nhập vào unity vs spring.net ...

Spring hiện làm CodeConfig nếu bạn không thích cấu hình XML

http://www.springframework.net/codeconfig/doc-latest/reference/html/

Ngoài ra, Spring không chỉ là một thùng chứa DI, nếu bạn nhìn vào phần 'Mô-đun' trong các tài liệu, thì thùng chứa DI là nền tảng của đống thứ khổng lồ mà nó làm.


3

Sửa lỗi cho tôi nếu tôi nhầm nhưng tôi nghĩ Autofac tự hỗ trợ Cấu hình XML như được liệt kê trong liên kết này: Cấu hình XML Autofac


2

Spring có một tính năng mà nó có thể đưa tham số vào hàm tạo hoặc thuộc tính dựa trên tên hoặc vị trí của tham số. Điều này rất hữu ích nếu tham số hoặc thuộc tính là một loại đơn giản (ví dụ: số nguyên, boolean). Xem ví dụ ở đây . Tôi không nghĩ rằng điều này thực sự bù đắp cho việc Spring không có khả năng cấu hình mã.

Windsor cũng có thể làm điều này, và có thể làm điều đó trong mã không cấu hình. (sửa tôi nếu tôi sai, tôi chỉ xem qua những gì tôi đã nghe ở đây).

Tôi muốn biết nếu Unity có thể làm điều này.


2

Một điều cần lưu ý: Ninject là bộ chứa IoC duy nhất hỗ trợ tiêm phụ thuộc theo ngữ cảnh (theo trang web của họ). Tuy nhiên, vì tôi không có kinh nghiệm với các bộ chứa IoC khác, tôi không thể biết liệu nó có giữ được không.


Nếu đây là tất cả "tiêm phụ thuộc theo ngữ cảnh" trong Ninject thì .. uhh, không có gì đặc biệt. Được hỗ trợ (bằng nhiều cách khác nhau) trong Unity, AutoFac, Windsor ít nhất.
dùng2864740 ngày

1

Chỉ cần thêm 2 xu của mình, tôi đã thử cả StructMap và Unity. Tôi tìm thấy StructMap là tài liệu kém / sai lầm, đau ở mông để cấu hình và sử dụng cồng kềnh. Tương tự, nó dường như không hỗ trợ các kịch bản như đối số của hàm tạo ghi đè tại thời điểm phân giải, đây là điểm sử dụng chính đối với tôi. Vì vậy, tôi đã bỏ nó và đi với Unity, và để nó làm những gì tôi muốn trong khoảng 20 phút.


1

Cá nhân tôi sử dụng Unity, nhưng chỉ vì nó là của Microsoft. Tôi lấy làm tiếc về quyết định này vì một lý do: điều lớn nhất mà nó chống lại nó có một "lỗi" lớn khiến nó liên tục ném ra ngoại lệ. Bạn có thể bỏ qua các ngoại lệ trong khi gỡ lỗi. Tuy nhiên, nó làm chậm ứng dụng của bạn rất nhiều nếu bạn chạy ngang qua nó, vì ném một ngoại lệ là một hoạt động tốn kém. Ví dụ: tôi hiện đang "sửa" ngoại lệ này tại một vị trí trong mã của mình, nơi các ngoại lệ của Unity thêm 4 giây vào thời gian kết xuất của trang. Để biết thêm chi tiết và cách giải quyết, xem:

Unity có thể được thực hiện để không ném đồng bộ hóa mọi lúc không?


Cảm ơn đã cảnh báo! Theo câu trả lời này từ câu hỏi mà bạn đề cập , lỗi hiện đã được giải quyết.
Sam

Tại sao Unity ném một ngoại lệ? Thông thường, một ngoại lệ là "lỗi nghiêm trọng" (chẳng hạn như sự phụ thuộc không thể khắc phục) và không phải là thứ gì đó để loại bỏ ..
user2864740 3/03/2015

Xin lỗi, đây có phải là "lỗi" đã được giải quyết hay bạn đã tìm ra cách để tránh nó? Bây giờ tôi đang chọn khung trong c # .net và háo hức muốn biết liệu sự thống nhất có còn là chi phí thời gian không ...
Chạy bộ Dan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.