在伪造和真实服务实现之间(Xamarin Forms)VSDryIoc切换

时间:2018-11-24 07:24:15

标签: c# dependency-injection xamarin.forms dryioc

我遇到一种情况,希望在运行时在“ 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?

2 个答案:

答案 0 :(得分:1)

使用容器解析实例后,应prevent removing or replacing registrations从容器中进行操作,这会带来复杂性,并可能导致非常微妙的,难以跟踪的错误,因为实例及其对象图的使用方式构造的可以缓存在DI容器中。您应该更喜欢保持对象图固定,从而在运行时不要更改图的形状。

解决方案是构建一个新的IBookingService服务性实现,该实现依赖于FakeBookingServiceRealBookingService并根据运行时信息将传入的呼叫转发给其中任何一个(您的开关)。这是代理模式的实现:

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