При использовании одноразового объекта таким способом следует помнить, что ссылка в контейнере также будет удалена, поэтому в идеале, когда вы возвращаете экземпляр через Resolve <>, он должен каждый раз возвращать новый экземпляр.
То, что вам нужно будет сделать, - это при регистрации типов в вашем контейнере разрешить ему указывать поведение: Shared (Singleton) или NonShared, например ::
.
Container.RegisterType<IDisposableObject>(CreationPolicy.NonShared);
using (var disposable = Container.Resolve<IDisposableObject>()) {
}
Вышеуказанное будет работать для экземпляров NonShared, поскольку каждый раз создается новый экземпляр, поэтому мы можем безопасно его утилизировать. Если вы попробовали описанное выше с CreationPolicy = Shared, синглтон был бы удален, поэтому в будущем доступ, скорее всего, приведет к исключению ObjectDisposedException.
Встраивая это поведение, вы можете создавать экземпляры Singleton, передавая CreationPolicy = Shared, например ::
Container.RegisterType<IUserRepository>(CreationPolicy.Shared);
using (var disposable = Container.Resolve<IDisposableObject>()) {
var userRepository = Container.Resolve<IUserRepository>();
// only one instance of user repository is created and persisted by the container.
}
Надеюсь, это поможет?
Эта терминология может быть знакома, если вы ранее использовали MEF.
РЕДАКТИРОВАТЬ : Итак, я понимаю, что вы хотите сделать что-то вроде:
using (var repository = Container.Resolve<IUserRepository>())
{
var other = Container.Resolve<IUserRepository>();
// should resolve to the same instance.
}
Вам нужно найти какой-нибудь способ наблюдения за одноразовым предметом в контейнере. Возможно, введите дополнительную политику создания SharedScope, например:
Container.Register<IUserRepository, UserRepository>(CreationPolicy.SharedScope);
Теперь, когда вы определяете тип с помощью контейнера, вам необходимо выяснить CreationPolicy элемента. Если элемент SharedScope, и он не был создан, создайте его экземпляр и верните.
Если вы разрешите экземпляр, и он уже создан, верните существующий экземпляр.
Когда Dispose вызывается для этого элемента, вам нужен какой-то способ для обратного вызова контейнера, чтобы удалить экземпляр.
РЕДАКТИРОВАТЬ ВТОРОЕ :
Ну, нет простого способа понять это. Единственный способ, которым я могу думать, - это ввести другой интерфейс:
public interface IMonitoredDisposable : IDisposable
{
bool IsDisposed { get; set; }
}
При удалении объекта убедитесь, что он устанавливает свойство IsDisposed. Не могли бы вы затем отслеживать это свойство из вашего контейнера?