我遇到一种情况,希望在运行时在“ FakeService”和“ RealService”之间切换。
MyViewModel
public class BookingViewModel
{
private readonly IBookingService bookingService;
public WelcomePageViewModel(
INavigationService navigationService,IBookingService bookingService)
{
this.bookingService= bookingService;
}
}
在我的App.xaml中,我按如下操作:
private IContainer container;
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
container = containerRegistry.GetContainer();
RegisterRealServices()
}
private void RegisterRealServices()
{
container.Register<IBookingService, RealBookingService>(Reuse.Singleton);
}
用户按下菜单选项以立即使用伪造的服务。因此,取消注册真实的服务并使用伪造的服务。
但是我在下面所做的事情似乎没有用,因为 我一直重定向到“ RealBookingService”,而不是“ FakeBookingService”
我该怎么办?
private void RegisterFakeServices()
{
container.Unregister<IBookingService>();
container.Register<IBookingService,FakeBookingService>(
Reuse.Singleton,
ifAlreadyRegistered: IfAlreadyRegistered.Replace);
}
问题:是否可以在运行时切换服务实现?如何使用DryIoc?
答案 0 :(得分:1)
使用容器解析实例后,应prevent removing or replacing registrations从容器中进行操作,这会带来复杂性,并可能导致非常微妙的,难以跟踪的错误,因为实例及其对象图的使用方式构造的可以缓存在DI容器中。您应该更喜欢保持对象图固定,从而在运行时不要更改图的形状。
解决方案是构建一个新的IBookingService
服务性实现,该实现依赖于FakeBookingService
和RealBookingService
并根据运行时信息将传入的呼叫转发给其中任何一个(您的开关)。这是代理模式的实现:
public class BookingServiceSelectorProxy : IBookingService
{
private readonly FakeBookingService fake;
private readonly RealBookingService real;
public BookingServiceSelectorProxy(FakeBookingService fake, RealBookingService real) {
this.fake = fake;
this.real = real;
}
private IBookingService BookingService =>
/* return fake or real based on your runtime switch */
// All methods dispatch to one of the wrapped repositories
public void CompleteBooking(CompleteBookingRequest request)
=> this.BookingService.CompleteBooking(request);
public void CancelBooking(CancelBookingRequest request)
=> this.BookingService.CancelBooking(request);
}
答案 1 :(得分:0)
我不是Xamarin方面的专家,但是要在DryIoc中注销(重新)需要特殊的准备(特别是对于单身人士)。这是因为服务创建可能已经被缓存。
这是Wiki,详细解释了这一点: https://bitbucket.org/dadhi/dryioc/wiki/UnregisterAndResolutionCache