我将在声明前面提出这个问题:我知道以下是糟糕的设计,但重构目前不是一个选项,理想情况下应该使用拦截器完成.
我正在努力将城堡从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>());
Run Code Online (Sandbox Code Playgroud)
RepositoryRegistration方法:
private static ComponentRegistration<TRepository> RepositoryRegistration<TRepository, TConcreteRepository>()
where TConcreteRepository : TRepository where TRepository : class
{
return Component
.For<TRepository>()
.ImplementedBy<TConcreteRepository>()
.Named(typeof(TConcreteRepository).Name);
}
Run Code Online (Sandbox Code Playgroud)
基础接口:
public interface IAccountRepository
{
string Create(Account account);
void Update(Account account);
Account Get(string accountId);
}
Run Code Online (Sandbox Code Playgroud)
实施:
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
}
}
Run Code Online (Sandbox Code Playgroud)
最后这是我在测试中得到的错误:
Castle.MicroKernel.Handlers.HandlerException:无法创建组件'AccountRepositoryFeedEntryDecorator',因为它具有要满足的依赖项.
'AccountRepositoryFeedEntryDecorator'正在等待以下依赖项: - 已注册但仍在等待依赖项的组件'Shaw.Services.CustomerManagement.Host.Repositories.Sql.Decorators.AccountRepositoryAuthorizationDecorator'(通过覆盖).
'Shaw.Services.CustomerManagement.Host.Repositories.Sql.Decorators.AccountRepositoryAuthorizationDecorator'正在等待以下依赖项: - 服务'AccountRepositoryFeedEntryDecorator'已注册,但也在等待依赖项.
乍一看似乎发生了某种循环依赖,但我真的不知道如何.
所以问题分为两部分,错误消息中组件和服务依赖规范之间的区别是什么,对错误的猜测是什么.
如果重要的是升级前的原始注册:
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>()
Run Code Online (Sandbox Code Playgroud)
装饰器注册按注册顺序进行,您无需指定依赖项,因此这将按您的预期工作:
container.Register(
RepositoryRegistration<IAccountRepository, AccountRepositoryFeedEntryDecorator>(),
RepositoryRegistration<IAccountRepository, AccountRepositoryAuthorizationDecorator>(),
RepositoryRegistration<IAccountRepository, AccountRepositoryMaskingDecorator>(),
RepositoryRegistration<IAccountRepository, AccountRepository>()
);
Run Code Online (Sandbox Code Playgroud)
解析一个实例IAccountRepository将产生一个AccountRepositoryFeedEntryDecorator,装饰一个AccountRepositoryAuthorizationDecorator,等等.
至于您的问题,此页面可以很好地解释服务,组件和依赖关系之间的差异,因为术语在库中使用.实质上:
在您的错误消息中,第一位是:
Castle.MicroKernel.Handlers.HandlerException:无法创建组件'AccountRepositoryFeedEntryDecorator',因为它具有要满足的依赖项.
好的,因此无法创建组件/类,因为无法满足其依赖性.它的依赖项是IAccountRepository decoratedRepository构造函数中的参数.
'AccountRepositoryFeedEntryDecorator'正在等待以下依赖项: - 已注册但仍在等待依赖项的组件'AccountRepositoryAuthorizationDecorator'(通过覆盖).
我们仍然在讨论相同的组件/类,并且它说它正在尝试使用组件/类AccountRepositoryAuthorizationDecorator来实现其依赖性,但该类也具有依赖性.
'AccountRepositoryAuthorizationDecorator'正在等待以下依赖项: - 已注册但仍在等待依赖项的服务'AccountRepositoryFeedEntryDecorator'.
而且我们已经到了第一类,所以存在循环依赖.这是因为设置的名称RepositoryRegistration与传入类型时计算的名称之间的断开连接Dependency.OnComponent.对于前者,您正在使用Type.Name(即"AccountRepositoryFeedEntryDecorator"),而后者使用Windsor Type.FullName(即"Your.Assembly.Name,AccountRepositoryFeedEntryDecorator").
由于命名不匹配,当Windsor尝试实现您指定的依赖项时,它将错过其注册,因为它具有不同的名称.因此,它可以在没有信息的情况下做到最好,并且(我假设)找到第一个IAccountRepository- 它不是组件本身 - 它可以作为依赖项插入.这种依赖性再次发生,这是我们开始的第一个组件,给出了循环依赖.
您可以通过删除Named注册部分或通过传递而不是类型本身typeof(AccountRepositoryAuthorizationDecorator).Name来解决这个问题Dependency.OnComponent.
| 归档时间: |
|
| 查看次数: |
487 次 |
| 最近记录: |