Вот пример дочерних областей связывания с Ninject:
var k = new StandardKernel();
k.Bind<Application>().ToSelf().InSingletonScope().DefinesNamedScope("Application");
k.Bind<UserRepository>().ToSelf().InNamedScope("Application");
const string userScopeName = "User";
k.Bind<UserScope>().ToSelf().DefinesNamedScope(userScopeName);
k.Bind<User>().ToSelf().InNamedScope(userScopeName);
k.Bind<User.ChatService>().ToSelf().InNamedScope(userScopeName);
k.Bind<User.SheetService>().ToSelf().InNamedScope(userScopeName);
const string nestedScopeName = "UserSheet";
k.Bind<User.Sheet>().ToSelf().DefinesNamedScope(nestedScopeName);
k.Bind<User.Sheet.SheetInfo>().ToSelf().InNamedScope(nestedScopeName);
k.Bind<User.Sheet.SheetCalculator>().ToSelf().InNamedScope(nestedScopeName);
Вы должны ссылаться Ninject.Extensions.NamedScope
и Ninject.Extensions.Factory
с Ninject.Extensions.ContextPreservatioon
.
Каждый Repository
может загружать несколько пользователей, и каждый из них будет иметь несколько Sheets
в «суб-областей»:
public class UserRepository
{
Func<UserScope> _factory;
[Inject]
public UserRepository(Func<UserScope> factory)
{
_factory = factory;
}
public UserScope LoadUser()
{
return _factory(); // scopes preserved
}
}
public class User
{
Func<Sheet> _sheetFactory; // multiple instances inside User scope
public UserRepository Repository { get; } // same instance for app
[Inject]
public User(Func<Sheet> sheetFactory, UserRepository repository)
{
Repository = repository;
_sheetFactory = sheetFactory;
}
public Sheet MakeSheet()
{
return _sheetFactory();
}
}
Это важно использовать UserScope
класс в качестве контейнера для User
, потому что в противном случае вы не можете решить тот же экземпляр User
внутри его зависимостей:
public class UserScope : IDisposable
{
[Inject]
public UserScope(User user, IResolutionRoot resolver)
{
User = user;
Resolver = resolver;
}
public User User { get; }
public IResolutionRoot Resolver { get; } // you can use this to resolve anything from inside **this** user scope
}
Затем вы можете загрузить пользователей, как:
var app = k.Get<Application>(); // singleton
var u1 = app.Repository.LoadUser();
var u2 = app.Repository.LoadUser();
И каждый из них будет иметь те же экземпляры Application
и Repository
, но разные экземпляры ChatService
и SheetService
.
Попробуйте Ninject - не уверенно на 100%. –
Unity - [с использованием дочерних контейнеров] (http://msdn.microsoft.com/en-us/library/dn178463 (v = pandp.30) .aspx # sec25) –
Что вы пытаетесь достичь? В большинстве контейнеров есть функция «образцовый образ жизни», который в большинстве случаев имеет тот же эффект. И для остальных случаев: вы не должны делать никаких регистраций после этапа запуска приложения. Я даже прочитал сообщение в блоге от Krzysztof Koźmic, что он сожалеет о том, что добавил эту функцию в Castle Windsor, поэтому я считаю, что такая функция действительно сомнительна. – Steven