Kesatuan Perpustakaan Perusahaan vs Wadah IoC Lainnya [ditutup]

135

Apa pro dan kontra menggunakan Enterprise Library Unity vs container IoC lainnya (Windsor, Spring.Net, Autofac ..)?

Yoann. B
sumber
9
Jenis pertanyaan ini selalu tertutup. Pendapat itu penting. Apakah ada tempat untuk menempatkannya?
Jeson Martajaya
1
@JesonMartajaya, saya ingin memuji komentar yang persis sama, itu menjengkelkan karena pertanyaannya semakin tertutup, tetapi tidak ada jawaban untuk alternatif.
Mohammed Noureldin

Jawaban:

234

Saya sedang mempersiapkan presentasi untuk grup pengguna. Karena itu saya baru saja membahas banyak dari mereka. Yaitu: AutoFac, MEF, Ninject, Spring.Net, StructureMap, Unity, dan Windsor.

Saya ingin memamerkan kasus 90% (injeksi konstruktor, yang terutama digunakan orang untuk IOC). Anda dapat melihat solusinya di sini (VS2008)

Karena itu, ada beberapa perbedaan utama:

  • Inisialisasi
  • Pengambilan objek

Masing-masing memiliki fitur lain juga (beberapa memiliki AOP, dan gizmos yang lebih baik, tetapi umumnya yang saya ingin IOC lakukan adalah membuat dan mengambil objek untuk saya)

Catatan: perbedaan antara pengambilan objek perpustakaan yang berbeda dapat dinegasikan dengan menggunakan CommonServiceLocator: http://www.codeplex.com/CommonServiceLocator

Itu membuat kita dengan inisialisasi, yang dilakukan dengan dua cara: melalui kode atau melalui konfigurasi XML (app.config / web.config / custom.config). Beberapa mendukung keduanya, beberapa hanya mendukung satu. Saya harus mencatat: beberapa menggunakan atribut untuk membantu IoC.

Jadi inilah penilaian saya tentang perbedaannya:

Ninject

Kode inisialisasi saja (dengan atribut). Saya harap Anda menyukai lambdas. Kode inisialisasi terlihat seperti ini:

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

StructureMap

Kode inisialisasi atau XML atau Atribut. v2.5 juga sangat lambda'y. Secara keseluruhan, ini adalah salah satu favorit saya. Beberapa ide yang sangat menarik tentang bagaimana StructureMap menggunakan Atribut.

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>();
 });

Kesatuan

Kode inisialisasi dan XML. Perpustakaan yang bagus, tetapi konfigurasi XML adalah menyebalkan. Perpustakaan yang bagus untuk Microsoft atau toko jalan raya. Inisialisasi kode itu mudah:

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

Spring.NET

XML hanya sedekat yang saya tahu. Tetapi untuk fungsionalitas Spring.Net melakukan segalanya di bawah matahari yang dapat dilakukan oleh IoC. Tetapi karena satu-satunya cara untuk menyatukan adalah melalui XML, ini biasanya dihindari oleh toko .net. Meskipun, banyak toko .net / Java menggunakan Spring.Net karena kesamaan antara Spring.Net versi .net dan proyek Java Spring.

Catatan : Konfigurasi dalam kode sekarang dimungkinkan dengan diperkenalkannya Spring.NET CodeConfig .

Windsor

XML dan kode. Seperti Spring.Net, Windsor akan melakukan apa pun yang Anda inginkan. Windsor mungkin adalah salah satu wadah IoC paling populer.

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

Autofac

Dapat mencampur XML dan kode (dengan v1.2). Perpustakaan IoC sederhana yang bagus. Tampaknya melakukan dasar-dasar dengan tidak banyak keributan. Mendukung kontainer bersarang dengan pelingkupan komponen lokal dan manajemen seumur hidup yang ditentukan dengan baik.

Inilah cara Anda memulainya:

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

Jika saya harus memilih hari ini: Saya mungkin akan menggunakan StructureMap. Ia memiliki dukungan terbaik untuk fitur bahasa C # 3.0, dan paling fleksibel dalam inisialisasi.

Catatan : Chris Brandsma mengubah jawaban aslinya menjadi postingan blog .

Chris Brandsma
sumber
1
Hanya konfigurasi Xml, membuatnya lebih sulit untuk dikonfigurasi. Pada dasarnya, satu-satunya orang yang saya lihat ingin menggunakan Spring.Net adalah mantan pengembang Java.
Chris Brandsma
Chris, sehubungan dengan kesimpulan Anda: dapatkah Anda menjelaskan lebih detail tentang a) fitur C # 3 yang Anda maksud, dan b) jenis inisialisasi apa yang penting bagi Anda? Terima kasih!
Nicholas Blumhardt
2
Hi Nicholas: untuk dukungan C # 3, semua yang sudah dilakukan Autofac. :) Untuk inisialisasi, saya ingin dukungan mudah untuk lajang / non lajang, dan inisialisasi per sesi. Akhirnya, saya ingin cara mudah untuk mereferensikan dengan nama kustom. (sesuatu yang merupakan PITA di StructureMap). Fitur terakhir yang lebih saya sukai sekarang daripada saat saya menulis ini aslinya: AutoMocking. Saya tidak menggunakannya sepanjang waktu, tetapi sangat menyenangkan memiliki arount.
Chris Brandsma
Anda menyebutkan MEF juga, saya menggunakan MEF untuk mengirimkan objek implementasi IRepository saya dan merasa itu berfungsi dengan baik. Apa pendapat Anda tentang MEF?
terjetyl
Berikut adalah screencast 20 menit yang bagus yang menampilkan sebagian besar Unity: pnpguidance.net/Screencast/…
Pat
7

Sejauh yang saya lihat, mereka hampir sama, kecuali untuk beberapa detail implementasi di sana-sini. Keuntungan terbesar yang dimiliki Unity atas persaingan adalah bahwa ini disediakan oleh Microsoft, ada banyak perusahaan di luar sana yang takut dengan OSS.

Salah satu kelemahannya adalah ini agak baru sehingga mungkin ada bug yang telah diselesaikan oleh pemain yang lebih lama.

Karena itu, Anda mungkin ingin memeriksanya .

rodbv
sumber
4

Utas lama tetapi karena ini adalah hal pertama yang ditunjukkan Google kepada saya ketika saya mengetik dalam unity vs spring.net ...

Spring melakukan CodeConfig sekarang jika Anda tidak menyukai konfigurasi XML

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

Juga, Spring jauh lebih dari sekedar wadah DI, jika Anda melihat bagian 'Modul' di dokumen, wadah DI adalah fondasi dari tumpukan besar hal-hal yang dilakukannya.

Richard
sumber
3

Perbaiki saya jika saya salah, tetapi menurut saya Autofac sendiri mendukung Konfigurasi XML seperti yang tercantum di tautan ini: Konfigurasi XML Autofac


sumber
2

Spring memiliki satu fitur yang dapat menginjeksi parameter ke konstruktor atau properti berdasarkan nama atau posisi parameter. Ini sangat berguna jika parameter atau properti adalah tipe sederhana (mis. Integer, boolean). Lihat contohnya di sini . Saya tidak berpikir bahwa ini benar-benar membuat ketidakmampuan Spring untuk melakukan konfigurasi dalam kode.

Windsor juga bisa melakukan ini, dan bisa melakukannya dalam kode bukan konfigurasi. (perbaiki saya jika saya salah, saya hanya akan melalui apa yang saya dengar di sini).

Saya ingin tahu apakah Unity bisa melakukan ini.

Anthony
sumber
2

Satu hal yang perlu diperhatikan: Ninject adalah satu-satunya wadah IoC yang mendukung injeksi ketergantungan kontekstual (sesuai situs Web mereka). Namun, karena saya tidak memiliki pengalaman dengan wadah IoC lainnya, saya tidak tahu apakah itu berlaku.

ehsanullahjan
sumber
Jika ini semua "injeksi ketergantungan kontekstual" ada di Ninject maka .. uhh, tidak ada yang istimewa. Didukung (dengan berbagai cara) di Unity, AutoFac, setidaknya Windsor.
pengguna2864740
1

Hanya untuk menambahkan 2 sen saya, saya sudah mencoba StructureMap dan Unity. Saya menemukan StructureMap tidak didokumentasikan dengan baik / salah, sulit dikonfigurasi, dan sulit digunakan. Demikian juga, tampaknya tidak mendukung skenario seperti penggantian argumen konstruktor pada waktu penyelesaian, yang merupakan titik penggunaan utama bagi saya. Jadi saya menjatuhkannya dan memilih Unity, dan membuatnya melakukan apa yang saya inginkan dalam waktu sekitar 20 menit.

Solusi Data Jacobs
sumber
1

Saya pribadi menggunakan Unity, tetapi hanya karena itu dari Microsoft. Saya menyesali keputusan tersebut karena satu alasan: hal terbesar yang menentangnya memiliki satu "bug" besar yang menyebabkannya terus-menerus mengeluarkan pengecualian. Anda dapat mengabaikan pengecualian saat melakukan debug. Namun memperlambat aplikasi Anda sangat jika Anda berjalan di atasnya, karena melemparkan eksepsi operasi yang mahal. Misalnya, saat ini saya "memperbaiki" pengecualian ini di satu tempat di kode saya di mana pengecualian Unity menambahkan 4 detik ekstra ke waktu render halaman. Untuk detail lebih lanjut dan solusi, lihat:

Bisakah Unity dibuat agar tidak membuang SynchronizationLockException sepanjang waktu?

Josh Mouch
sumber
Terima kasih atas peringatannya! Menurut jawaban dari pertanyaan yang Anda rujuk , bug tersebut sekarang telah teratasi.
Sam
Mengapa Unity membuat pengecualian? Biasanya pengecualian adalah 'kesalahan kritis' (seperti ketergantungan yang tidak dapat dipulihkan) dan bukan sesuatu yang harus ditekan ..
user2864740
Permisi, Apakah "bug" ini sudah teratasi atau sudahkah Anda menemukan cara untuk menghindarinya? Saya memilih kerangka kerja di c # .net sekarang dan ingin tahu apakah persatuan masih memakan waktu ...
Jog Dan