Điều này đã khiến tôi băn khoăn thường xuyên. Mặc dù không hài lòng về nó, tôi luôn luôn đi đến kết luận rằng không bao giờ trở về một đối tượng IDisposable một cách thoáng qua là tốt nhất.
Gần đây, tôi đã lặp lại câu hỏi cho chính mình: Đây có phải là vấn đề của IoC hay vấn đề về khung .net? Xử lý là khó xử anyway. Nó không có mục đích chức năng có ý nghĩa, chỉ mang tính kỹ thuật. Vì vậy, nó là một vấn đề khuôn khổ mà chúng ta phải đối phó, hơn là một vấn đề IoC.
Điều tôi thích về DI là tôi có thể yêu cầu hợp đồng cung cấp chức năng cho tôi mà không phải lo lắng về chi tiết kỹ thuật. Tôi không phải là chủ sở hữu. Không có kiến thức về lớp mà nó ở. Không có kiến thức về những công nghệ được yêu cầu để thực hiện hợp đồng, không phải lo lắng về cuộc đời. Mã của tôi trông đẹp và sạch sẽ, và có khả năng kiểm tra cao. Tôi có thể thực hiện trách nhiệm trong các lớp mà họ thuộc về.
Vì vậy, nếu có ngoại lệ đối với quy tắc này yêu cầu tôi phải tổ chức toàn bộ thời gian, hãy tạo ngoại lệ đó. Cho dù tôi có thích hay không. Nếu đối tượng thực hiện giao diện yêu cầu tôi phải vứt bỏ nó, tôi muốn biết về nó kể từ đó tôi được kích hoạt để sử dụng đối tượng càng ngắn càng tốt. Một thủ thuật bằng cách giải quyết nó bằng cách sử dụng một thùng chứa trẻ em được xử lý một thời gian sau đó có thể vẫn khiến tôi giữ vật thể sống lâu hơn tôi nên. Thời gian cho phép của đối tượng được xác định khi đăng ký đối tượng. Không phải bởi các chức năng tạo ra một container con và giữ cho rằng trong một thời gian nhất định.
Vì vậy, miễn là chúng tôi phát triển cần phải lo lắng về việc xử lý (sẽ thay đổi bao giờ?) Tôi sẽ cố gắng tiêm càng ít đối tượng dùng một lần càng tốt. 1. Tôi cố gắng để làm cho đối tượng không IDisposable, ví dụ bằng cách không giữ các đối tượng dùng một lần trên cấp lớp, nhưng trong một phạm vi nhỏ hơn. 2. Tôi cố gắng làm cho đối tượng có thể tái sử dụng để có thể áp dụng một trình quản lý lâu dài khác.
Nếu điều này là không khả thi, tôi sử dụng một nhà máy để cho biết rằng người dùng của hợp đồng được tiêm là chủ sở hữu và phải chịu trách nhiệm về nó.
Có một cảnh báo: thay đổi người triển khai hợp đồng từ không dùng một lần sang dùng một lần sẽ là một thay đổi đột phá. Vào thời điểm đó giao diện sẽ không còn được đăng ký, nhưng giao diện cho nhà máy.Nhưng tôi nghĩ điều này cũng áp dụng cho các kịch bản khác. Việc quên sử dụng một thùng chứa con sẽ từ thời điểm đó khi đưa ra các vấn đề về bộ nhớ. Cách tiếp cận nhà máy sẽ gây ra một IoC giải quyết ngoại lệ.
Một số mã ví dụ:
using System;
using Microsoft.Practices.Unity;
namespace Test
{
// Unity configuration
public class ConfigurationExtension : UnityContainerExtension
{
protected override void Initialize()
{
// Container.RegisterType<IDataService, DataService>(); Use factory instead
Container.RegisterType<IInjectionFactory<IDataService>, InjectionFactory<IDataService, DataService>>();
}
}
#region General utility layer
public interface IInjectionFactory<out T>
where T : class
{
T Create();
}
public class InjectionFactory<T2, T1> : IInjectionFactory<T2>
where T1 : T2
where T2 : class
{
private readonly IUnityContainer _iocContainer;
public InjectionFactory(IUnityContainer iocContainer)
{
_iocContainer = iocContainer;
}
public T2 Create()
{
return _iocContainer.Resolve<T1>();
}
}
#endregion
#region data layer
public class DataService : IDataService, IDisposable
{
public object LoadData()
{
return "Test data";
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
/* Dispose stuff */
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
#endregion
#region domain layer
public interface IDataService
{
object LoadData();
}
public class DomainService
{
private readonly IInjectionFactory<IDataService> _dataServiceFactory;
public DomainService(IInjectionFactory<IDataService> dataServiceFactory)
{
_dataServiceFactory = dataServiceFactory;
}
public object GetData()
{
var dataService = _dataServiceFactory.Create();
try
{
return dataService.LoadData();
}
finally
{
var disposableDataService = dataService as IDisposable;
if (disposableDataService != null)
{
disposableDataService.Dispose();
}
}
}
}
#endregion
}
Giải pháp của tôi là sử dụng một IoC với quản lý đời phù hợp và tốt hệ thống hóa: AutoFac và Lâu đài Windsor có như vậy (mặc dù họ làm việc hơi khác nhau); Đơn vị 2.1 chỉ đơn giản là thất bại khi giao dịch với transients dưới các nhà quản lý suốt đời mặc định .. – user2864740