Dường như có sự kỳ thị về SO liên quan đến việc sử dụng Singletons. Tôi đã không bao giờ cá nhân mua vào nó, nhưng vì lợi ích cởi mở cởi mở, tôi đang cố gắng để cung cấp cho các khái niệm IoC một thử là một thay thế bởi vì tôi thẳng thắn chán với công việc hàng ngày của tôi và muốn thử một cái gì đó khác nhau. Tha thứ cho tôi nếu diễn giải của tôi về khái niệm IoC là không đúng hoặc sai lầm.Lợi ích của IoC đối với Nhà máy của tôi Singleton
Đây là tình huống: Tôi đang xây dựng một máy chủ web đơn giản HttpListener
dựa trên cửa sổ sử dụng mô hình trình cắm để xác định cách xử lý yêu cầu dựa trên URL được yêu cầu (giống như mọi người khác hỏi về HttpListener
). Cách tiếp cận của tôi để khám phá các trình cắm thêm là truy vấn một thư mục được cấu hình cho các assembly được trang trí với một HttpModuleAssemblyAttribute
. Những hội đồng này có thể chứa 0 hoặc nhiều hơn IHttpModule
trẻ em ngoài ra được trang trí với HttpModuleAttribute
được sử dụng để chỉ định tên, phiên bản, mô tả có thể đọc được của con người và nhiều thông tin khác. Một cái gì đó như:
[HttpModule(/*Some property values that matter */)]
public class SimpleHttpModule : IHttpModule
{
public void Execute(HttpListenerContext context)
{
/* Do Something Special */
}
}
Khi một HttpModule
được phát hiện tôi thường sẽ thêm nó vào một đối tượng Dictionary<string, Type>
người là mục đích duy nhất là để theo dõi những mô-đun chúng ta biết về. Từ điển này thường sẽ sống trong một loạt các Singleton của tôi mà mất trên persona của một ACE style Singleton (một di sản từ ngày C++ của tôi, nơi tôi đã học được về Singletons).
Bây giờ những gì tôi đang cố gắng thực hiện là một cái gì đó tương tự bằng cách sử dụng (hiểu biết của tôi về) khái niệm chung của IoC. Về cơ bản những gì tôi có là một AppService
bộ sưu tập nơi IAppService
được định nghĩa là:
public interface IAppService : IDisposable
{
void Initialize();
}
Và tôi plug-in AppService
sẽ giống như thế:
[AppService("Plugins")]
internal class PluginAppService : IAppService, IDictionary<string, Type>
{
/* Common IDictionary Implementation consisting of something like: */
internal Type Item(string modName)
{
Type modType;
if (!this.TryGetValue(modName, out modType)
return null;
return modType;
}
internal void Initialize()
{
// Find internal and external plug-ins and add them to myself
}
// IDisposable clean up method that attempts to dispose all known plug-ins
}
Sau đó, trong quá trình dịch vụ OnStart
tôi nhanh chóng một thể hiện của AppServices
mà được biết tại địa phương nhưng được truyền cho nhà xây dựng của tất cả các trình cắm được khởi tạo:
public class AppServices : IDisposable, IDictionary<string, IAppService>
{
/* Simple implementation of IDictionary */
public void Initialization()
{
// Find internal IAppService implementations, instantiate them (passing this as a constructor parameter), initialize them and add them to this.
// Somewhere in there would be something like
Add(appSvcName, appSvc);
}
}
chúng tôi phương pháp một lần duy nhất thực hiện trở thành một thực hiện trừu tượng + một constructor trên con:
[HttpModule(/*Some property values that matter */)]
public abstract class HttpModule : IHttpModule
{
protected AppServices appServices = null;
public HttpModule(AppServices services)
{
appServices = services;
}
public abstract void Execute(HttpListenerContext context);
}
[HttpModule(/*Some property values that matter */)]
public class SimpleHttpModule : HttpModule
{
public SimpleHttpModule(AppServices services) : base(services) { }
public override void Execute(HttpListenerContext context)
{
/* Do Something Special */
}
}
Và bất kỳ quyền truy cập vào các dịch vụ ứng dụng thường được sử dụng trở thành:
var plugType = appServices["Plugins"][plugName];
hơn:
var plugType = PluginManager.Instance[plugName];
Tôi có thiếu một số khái niệm cơ bản của IoC ở đây để đơn giản hóa tất cả hoặc có thực sự là một lợi ích cho tất cả các mã bổ sung này? Trong thế giới của tôi, Singletons là những sinh vật đơn giản cho phép mã trong suốt một chương trình truy cập thông tin cần thiết (tương đối tĩnh) (trong trường hợp này là các loại).
Để đặt ra các câu hỏi một cách rõ ràng hơn:
- Đây có phải là một việc thực hiện hợp lệ của một Singleton Factory dịch sang khái niệm IoC/DI?
- Nếu có, đâu là hoàn vốn/lợi ích cho mã bổ sung được yêu cầu và áp dụng API có vẻ phức tạp hơn?
Có thể bạn không nhận được câu trả lời mà bạn đang tìm kiếm vì câu hỏi của bạn quá mơ hồ (mặc dù quá dài). Bạn nên thực sự hình chính xác câu hỏi nào bạn muốn trả lời và hỏi nó. –
Tôi nghĩ rằng phản ứng dữ dội chung đối với các single là do chúng là một phương thức giới thiệu trạng thái toàn cầu vào một ứng dụng, chạy ngược với thiết kế hướng đối tượng. Họ cũng thường xuyên khó kiểm tra đơn vị. –
@DBM - Trạng thái toàn cầu phản đối OOP? Làm thế nào? Nó thường là một cách tiếp cận được chấp nhận trong C++ (cũng là OO). –