1

「子スコープ」の概念を持つ .NET DI コンテナーはありますか?

何かのようなもの:

var container = AppConfiguredContainer();

using(var childContainer = container.GetChild())
{
  childContainer.Register<IFoo>(typeof(Foo));

  // do stuff with childContainer
}

ポイントは、子コンテナーで行われるサービスの構成は、アプリケーション全体の構成に影響しないということです。

4

1 に答える 1

0

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.NamedScopeNinject.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();

そして、それらのそれぞれは、 and の同じインスタンスをApplication持ちますが、 andRepositoryのインスタンスは異なります。ChatServiceSheetService

于 2016-03-19T22:49:40.567 に答える