gpt4 book ai didi

c# - 组件和服务依赖项之间有什么区别?

转载 作者:太空狗 更新时间:2023-10-29 21:27:34 24 4
gpt4 key购买 nike

我将在这个问题的开头声明:我知道以下是糟糕的设计,但重构目前不是一个选项,理想情况下应该使用拦截器来完成。

我正在努力将 caSTLe 从 1.6(我认为)升级到 3.3,不幸的是,这涉及一些语法更改,我现在已经编译了所有内容,但我围绕服务容器的一些测试无法正常工作。

我有一个存储库,它有多个实现来提供不同的功能,该存储库只用于内联的所有不同实现,这里是代码的基础:

温莎城堡注册:

RepositoryRegistration<IAccountRepository, AccountRepositoryFeedEntryDecorator>()
.DependsOn(Dependency.OnComponent("decoratedRepository", typeof(AccountRepositoryAuthorizationDecorator))),
RepositoryRegistration<AccountRepositoryAuthorizationDecorator>()
.DependsOn(Dependency.OnComponent("decoratedRepository", typeof(AccountRepositoryMaskingDecorator))),
RepositoryRegistration<AccountRepositoryMaskingDecorator>()
.DependsOn(Dependency.OnComponent("decoratedRepository", typeof(AccountRepository))),
RepositoryRegistration<AccountRepository>());

RepositoryRegistration 方法:

private static ComponentRegistration<TRepository> RepositoryRegistration<TRepository, TConcreteRepository>()
where TConcreteRepository : TRepository where TRepository : class
{
return Component
.For<TRepository>()
.ImplementedBy<TConcreteRepository>()
.Named(typeof(TConcreteRepository).Name);
}

基础接口(interface):

public interface IAccountRepository
{
string Create(Account account);
void Update(Account account);
Account Get(string accountId);
}

实现:

public class AccountRepositoryFeedEntryDecorator : IAccountRepository
{
private readonly IAccountRepository decoratedRepository;
public AccountRepositoryFeedEntryDecorator(
IAccountRepository decoratedRepository)
{
this.decoratedRepository = decoratedRepository;
}

string Create(Account account)
{
//Add Entry To Feed
return decoratedRepository.Create(account);
};

void Update(Account account)
{
//Add Entry To Feed
return decoratedRepository.Udpate(account);
}
Account Get(string accountId);
{
//Add Entry To Feed
return decoratedRepository.Get(accountId);
}
}

public class AccountRepositoryAuthorizationDecorator : IAccountRepository
{
private readonly IAccountRepository decoratedRepository;
public AccountRepositoryAuthorizationDecorator(
IAccountRepository decoratedRepository)
{
this.decoratedRepository = decoratedRepository;
}

string Create(Account account)
{
//Ensure User Is Authorized
return decoratedRepository.Create(account);
};

void Update(Account account)
{
//Ensure User Is Authorized
return decoratedRepository.Udpate(account);
}
Account Get(string accountId);
{
//Ensure User Is Authorized
return decoratedRepository.Get(accountId);
}
}

public class AccountRepositoryMaskingDecorator : IAccountRepository
{
private readonly IAccountRepository decoratedRepository;
public AccountRepositoryMaskingDecorator(
IAccountRepository decoratedRepository)
{
this.decoratedRepository = decoratedRepository;
}

string Create(Account account)
{
//Mask Sensitive Information
return decoratedRepository.Create(account);
};

void Update(Account account)
{
//Mask Sensitive Information
return decoratedRepository.Udpate(account);
}
Account Get(string accountId);
{
//Mask Sensitive Information
return decoratedRepository.Get(accountId);
}
}

public class AccountRepository : IAccountRepository
{
string Create(Account account)
{
//Create account and return details
};

void Update(Account account)
{
//Update account and return details
}
Account Get(string accountId);
{
//Return Account
}
}

最后是我在测试中遇到的错误:

Castle.MicroKernel.Handlers.HandlerException : Can't create component 'AccountRepositoryFeedEntryDecorator' as it has dependencies to be satisfied.

'AccountRepositoryFeedEntryDecorator' is waiting for the following dependencies: - Component 'Shaw.Services.CustomerManagement.Host.Repositories.Sql.Decorators.AccountRepositoryAuthorizationDecorator' (via override) which was registered but is also waiting for dependencies.

'Shaw.Services.CustomerManagement.Host.Repositories.Sql.Decorators.AccountRepositoryAuthorizationDecorator' is waiting for the following dependencies: - Service 'AccountRepositoryFeedEntryDecorator' which was registered but is also waiting for dependencies.

乍一看似乎发生了某种循环依赖,但我真的看不出是怎么回事。

所以问题分为两部分,错误消息中的组件和服务依赖规范之间的区别是什么,关于哪里出了问题的任何猜测。

如果这里重要的是升级前的原始注册:

RepositoryRegistration<IAccountRepository, AccountRepositoryFeedEntryDecorator>()
.ServiceOverrides(new { decoratedRepository = typeof(AccountRepositoryAuthorizationDecorator).Name }),
RepositoryRegistration<AccountRepositoryAuthorizationDecorator>()
.ServiceOverrides(new { decoratedRepository = typeof(AccountRepositoryMaskingDecorator).Name }),
RepositoryRegistration<AccountRepositoryMaskingDecorator>()
.ServiceOverrides(new { decoratedRepository = typeof(AccountRepository).Name }),
RepositoryRegistration<AccountRepository>()

最佳答案

装饰器注册按注册顺序进行,您不需要指定依赖项,因此这会像您期望的那样工作:

container.Register(
RepositoryRegistration<IAccountRepository, AccountRepositoryFeedEntryDecorator>(),
RepositoryRegistration<IAccountRepository, AccountRepositoryAuthorizationDecorator>(),
RepositoryRegistration<IAccountRepository, AccountRepositoryMaskingDecorator>(),
RepositoryRegistration<IAccountRepository, AccountRepository>()
);

解析 IAccountRepository 的实例将产生一个 AccountRepositoryFeedEntryDecorator,它装饰了一个 AccountRepositoryAuthorizationDecorator


关于您的问题,this page很好地解释了服务、组件和依赖项之间的差异,因为这些术语在库中使用。本质上:

  • 服务 是一些功能契约,通常是接口(interface)或委托(delegate)。它是抽象的。
  • 组件 是服务的实现,通常是类。它是具体的。
  • 依赖性是组件使用的服务。

在您的错误消息中,第一位是:

Castle.MicroKernel.Handlers.HandlerException : Can't create component 'AccountRepositoryFeedEntryDecorator' as it has dependencies to be satisfied.

好的,所以无法创建组件/,因为无法满足其依赖性。它的依赖项是构造函数中的 IAccountRepository decoratedRepository 参数。

'AccountRepositoryFeedEntryDecorator' is waiting for the following dependencies: - Component 'AccountRepositoryAuthorizationDecorator' (via override) which was registered but is also waiting for dependencies.

我们仍在谈论同一个组件/类,它说它试图使用组件/类 AccountRepositoryAuthorizationDecorator 来实现其依赖性,但该类也有依赖性。

'AccountRepositoryAuthorizationDecorator' is waiting for the following dependencies: - Service 'AccountRepositoryFeedEntryDecorator' which was registered but is also waiting for dependencies.

我们已经回到了第一类,所以存在循环依赖。这是因为 RepositoryRegistration 中设置的名称与将类型传递给 Dependency.OnComponent 时计算的名称之间存在脱节。对于前者,您正在使用 Type.Name(即“AccountRepositoryFeedEntryDecorator”),对于后者,Windsor 在幕后使用 Type.FullName(即“您的.Assembly.Name,AccountRepositoryFeedEntryDecorator”)。

由于命名不匹配,当 Windsor 尝试实现您指定的依赖项时,它将错过对其的注册,因为它具有不同的名称。结果,它在没有信息的情况下尽力而为,并且(我假设)找到了第一个 IAccountRepository——这不是组件本身——它可以作为依赖项插入。这种依赖性再次发生,这是我们开始使用的第一个组件,提供循环依赖性。

您可以通过删除注册的 Named 部分或将 typeof(AccountRepositoryAuthorizationDecorator).Name 传递给 Dependency.OnComponent 来解决这个问题> 而不是类型本身。

关于c# - 组件和服务依赖项之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25631281/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com