我有一个简单的框架,它将允许“一切”订阅事件,因为“警卫”已经通过。声明它的语法如下所示:
public class MyObject : ICanHandle<MySuperAwesomeEvent, GivenYouAreLeetGuard> { .... }守卫可以通过两种不同的方式创建。通过使用此扩展方法在容器中注册
public static void RegisterCommandGuard<TCommandGuard>(this ContainerBuilder builder)
where TCommandGuard : IExecuteGuard
{
var type = typeof(TCommandGuard);
var typeName = type.FullName;
builder.RegisterType<TCommandGuard>().Named(typeName, type);
}或者,它将通过在我的框架中解决这个组件时使用反射来创建。
public bool CanExecute(object message)
{
object resolvedType = null;
var name = CanExecuteGuard.FullName;
if(!_componentContext.TryResolveNamed(name, typeof(IExecuteGuard), out resolvedType))
{
try
{
resolvedType = (IExecuteGuard)Activator.CreateInstance(CanExecuteGuard);
}
catch (Exception e)
{
throw new Exception($"Cannot locate {name} in container nor create an instance of it. See inner exception:", e);
}
}
return ((IExecuteGuard)resolvedType).CanExecute(message);
}在我的应用程序中运行这一点正如我所期望的那样,但是在我的测试中,我无法解决任何“警卫”问题。
[Fact]
public void EventAggregator_GivenGuardWithDependencies_ShouldFireEventToAllSubscribers()
{
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<UserRepository>().As<IUserRepository>();
containerBuilder.RegisterCommandGuard<MustBeAdminGuard>();
var container = containerBuilder.Build();
using (var lifeTimeScope = container.BeginLifetimeScope())
{
var eventAggregator = new ExtendedEventAggregator(lifeTimeScope);
var @object = new ObjectWhichHandlesUsers();
eventAggregator.Subscribe(@object);
eventAggregator.PublishOnUIThread(new FireEmployeeCommand(userId: 1, userToFireId: 5));
@object.UserIds.Should().HaveCount(6);
}
}TryResolveNamed方法在IComponentContext中永远找不到我的注册守卫。查看调试器,我可以清楚地看到“某事”是以某种方式注册的。

我在这里做错什么了?关于如何改进代码的其他建议也提供了评论。谢谢!
编辑:
在调试单元测试期间,我试图通过在Visual的Immidiate窗口中键入以下内容来检查是否注册了卫队:
lifeTimeScope.IsRegisteredWithName("Caliburn.Micro.Demo.Tests.MustBeAdminGuard",typeof(MustBeAdminGuard))这个查询返回true。传递IComponentContext而不是ILifeTimeScope的真正区别是什么?我认为这个接口只公开了ILifeTimeScope公开的方法的一个子集。
发布于 2019-01-01 14:15:21
我有类似于我自己的测试smth,它正在工作,但我知道您的问题在哪里,您已经注册了MustBeAdminGuard类型,并且您希望解决不同类型的IExecuteGuard,所以不要期望它会像这样工作:)
因此,要解决这个问题,您必须更改类RegisterCommandGuard中的注册部分。你有两种选择你想要的
//1. looks better
builder.RegisterType<TCommandGuard>().Named<IExecuteGuard>(typeName);
//2.
builder.RegisterType<TCommandGuard>().Named(typeName, typeof(IExecuteGuard));让我知道,如果它解决了你的问题,它必须^^,因为我已经在普通的例子中测试过它。
https://stackoverflow.com/questions/53846452
复制相似问题