Saya ingin meneruskan nilai ke konstruktor di kelas yang mengimplementasikan layanan saya.
Namun ServiceHost hanya mengizinkan saya meneruskan nama jenis yang akan dibuat, bukan argumen apa yang harus diteruskan ke pembuatnya.
Saya ingin lulus di pabrik yang membuat objek servis saya.
Apa yang saya temukan sejauh ini:
- Perilaku Injeksi Ketergantungan WCF yang melebihi apa yang saya cari dan tampaknya terlalu rumit untuk kebutuhan saya.
wcf
dependency-injection
factory-pattern
Ian Ringrose
sumber
sumber
Jawaban:
Anda harus menerapkan kombinasi ubahsuaian
ServiceHostFactory
,ServiceHost
danIInstanceProvider
.Diberikan layanan dengan tanda tangan konstruktor ini:
Berikut adalah contoh yang dapat menjalankan MyService:
Daftarkan MyServiceHostFactory di file MyService.svc Anda, atau gunakan MyServiceHost secara langsung dalam kode untuk skenario hosting mandiri.
Anda dapat dengan mudah menggeneralisasi pendekatan ini, dan kenyataannya beberapa Kontainer DI telah melakukan ini untuk Anda (petunjuk: Fasilitas WCF Windsor).
sumber
protected
saya tidak bisa memanggilnya sendiri dari Main ()dep
ke dalam setiap InstanceProvider Kontrak . Anda dapat melakukan: diImplementedContracts.Values.First(c => c.Name == "IMyService").ContractBehaviors.Add(new MyInstanceProvider(dep));
manaIMyService
antarmuka kontrak AndaMyService(IDependency dep)
. Jadi, masukkanIDependency
hanya ke InstanceProvider yang benar-benar membutuhkannya.Anda cukup membuat dan instance dari Anda
Service
dan meneruskan instance itu keServiceHost
objek. Satu-satunya hal yang harus Anda lakukan adalah menambahkan[ServiceBehaviour]
atribut untuk layanan Anda dan menandai semua objek yang dikembalikan dengan[DataContract]
atribut.Ini mock upnya:
dan penggunaan:
Saya berharap ini akan membuat hidup seseorang lebih mudah.
sumber
InstanceContextMode.Single
).Jawaban Markus dengan
IInstanceProvider
benar.Daripada menggunakan ServiceHostFactory kustom, Anda juga bisa menggunakan atribut kustom (misalnya
MyInstanceProviderBehaviorAttribute
). Turunkan dariAttribute
, buat itu menerapkanIServiceBehavior
dan menerapkanIServiceBehavior.ApplyDispatchBehavior
metode sepertiKemudian, terapkan atribut ke kelas implementasi layanan Anda
Opsi ketiga: Anda juga dapat menerapkan perilaku layanan menggunakan file konfigurasi.
sumber
Saya bekerja dari jawaban Mark, tetapi (untuk skenario saya setidaknya), itu sangat rumit. Salah satu
ServiceHost
konstruktor menerima sebuah instance layanan, yang bisa Anda teruskan langsung dariServiceHostFactory
implementasi.Untuk mendukung contoh Mark, akan terlihat seperti ini:
sumber
instance
. Itu mungkin atau mungkin tidak memengaruhi kinerja. Jika Anda ingin dapat menangani permintaan berbarengan, seluruh grafik objek tersebut harus aman untuk thread, atau Anda akan mendapatkan perilaku non-deterministik, perilaku yang salah. Jika Anda bisa menjamin keamanan benang, solusi saya memang sangat rumit. Jika Anda tidak dapat menjamin itu, solusi saya diperlukan.Persetan ... Saya memadukan injeksi ketergantungan dan pola pelacak layanan (tetapi kebanyakan itu masih injeksi ketergantungan dan bahkan terjadi di konstruktor yang berarti Anda dapat memiliki status hanya-baca).
Dependensi layanan dengan jelas ditentukan dalam kontrak
Dependencies
kelas bertingkatnya . Jika Anda menggunakan kontainer IoC (yang belum memperbaiki kekacauan WCF untuk Anda), Anda dapat mengonfigurasinya untuk membuatDependencies
instance, bukan layanan. Dengan cara ini Anda mendapatkan perasaan fuzzy hangat yang diberikan oleh wadah Anda sementara juga tidak harus melewati terlalu banyak rintangan yang diberlakukan oleh WCF.Saya tidak akan kehilangan waktu tidur karena pendekatan ini. Begitu pula seharusnya orang lain. Bagaimanapun, wadah IoC Anda adalah kumpulan delegasi statis yang besar, gemuk, dan statis yang menciptakan berbagai hal untuk Anda. Apa menambahkan satu lagi?
sumber
Kami menghadapi masalah yang sama ini dan menyelesaikannya dengan cara berikut. Ini adalah solusi sederhana.
Dalam Visual Studio cukup buat aplikasi layanan WCF normal dan hapus antarmuka itu. Biarkan file .cs di tempatnya (cukup ganti namanya) dan buka file cs itu dan ganti nama antarmuka dengan nama kelas asli Anda yang mengimplementasikan logika layanan (dengan cara ini kelas layanan menggunakan pewarisan dan menggantikan implementasi Anda yang sebenarnya). Tambahkan konstruktor default yang memanggil konstruktor kelas dasar, seperti ini:
Kelas dasar MyService adalah implementasi aktual dari layanan. Kelas dasar ini tidak boleh memiliki konstruktor tanpa parameter, tetapi hanya konstruktor dengan parameter yang menerima dependensi.
Layanan harus menggunakan kelas ini, bukan MyService asli.
Ini solusi sederhana dan bekerja seperti pesona :-D
sumber
Ini adalah solusi yang sangat membantu - terutama untuk seseorang yang merupakan pembuat kode WCF pemula. Saya memang ingin memposting sedikit tip untuk setiap pengguna yang mungkin menggunakan ini untuk layanan yang dihosting IIS. MyServiceHost perlu mewarisi WebServiceHost , bukan hanya ServiceHost.
Ini akan membuat semua binding yang diperlukan, dll. Untuk endpoint Anda di IIS.
sumber
Saya menggunakan variabel statis tipe saya. Tidak yakin apakah ini cara terbaik, tetapi berhasil untuk saya:
Ketika saya memberi contoh host layanan, saya melakukan hal berikut:
sumber