Caliburn Micro获取服务实例

时间:2015-04-24 06:32:04

标签: c# windows-store-apps windows-phone-8.1 caliburn.micro

我正在使用Caliburn Micro for WinRT应用程序。我在App.xaml.cs中注册了一项服务,请参阅下面的示例代码

public sealed partial class App
    {
        private WinRTContainer _container;

      public App()
        {
            InitializeComponent();
            Resuming += AppResuming;
        }

        protected override void Configure()
        {
            _container = new WinRTContainer();

            _container.RegisterWinRTServices();

            _container.Singleton<ISampleService, SampleService>();
            //some more viewmodels & services added
        }

protected override void PrepareViewFirst(Frame rootFrame)
        {
            _container.RegisterNavigationService(rootFrame);
        }

protected override object GetInstance(Type service, string key)
        {
            return _container.GetInstance(service, key);
        }

        protected override IEnumerable<object> GetAllInstances(Type service)
        {
            return _container.GetAllInstances(service);
        }

        protected override void BuildUp(object instance)
        {
            _container.BuildUp(instance);
        }
}

现在,我有一个实用工具类,我想在其中获取此SampleService的实例。

我如何获得实例?

3 个答案:

答案 0 :(得分:2)

我假设您正在使用MEF和Caliburn.Micro

所以你可以这样得到一个实例:

SampleService service = IoC.Get<ISampleService>();

希望这会对你有所帮助。

答案 1 :(得分:2)

Guerudo的答案有效,但除非绝对必须,否则不应使用IoC.Get<>。使用服务定位器被视为反模式。

获取实例的权利是使用构造函数注入。假设您有MainViewModel,请执行此操作

public class MainViewModel
{
    private readonly ISampleService _sampleService;

    public MainViewModel(ISampleService sampleService)
    {
        _sampleService = sampleService   
    }

}

在ViewModel的任何位置使用_sampleService。

Caliburn.Micro不需要任何MEF属性。

答案 2 :(得分:1)

在大多数情况下,您应该避免直接从容器中取出物品。相反,请考虑使用依赖注入。

例如,如果要在ISampleService类中使用SomeUtility,这是从SomeViewModel调用的,那么首先需要在容器中注册所有三种类型。

public class AppBootstrapper : BootstrapperBase
{
    protected override void Configure()
    {
        ...

        _container.Singleton<ISampleService, SampleService>();
        _container.Singleton<SomeUtility>();
        _container.PerRequest<SomeViewModel>();
    }
}

现在,由于SomeUtility取决于ISampleService,您应该创建SomeUtility构造函数,它将接受ISampleService

class SomeUtility
{
    private ISampleService _service;

    public SomeUtility(ISampleService service)
    {
        _service = service;
    }
}

如果SomeViewModel将使用SomeUtility,那么相应的构造函数也应添加到SomeViewModel

class SomeViewModel : Caliburn.Micro.Screen
{
    private SomeUtility _utility;

    public SomeViewModel(SomeUtility utility)
    {
        _utility = utility;
    }
}

最后,让我们将SomeViewModel添加到ShellViewModel构造函数中。

class ShellViewModel : PropertyChangedBase, IShell
{
    private SomeViewModel _vm;

    public ShellViewModel(SomeViewModel vm)
    {
        _vm = vm;
    }
}

那就是它! ShellViewModel将获得SomeViewModel个实例,SomeViewModel将获得SomeUtilitySomeUtility将获得ISampleService。所有这些都将由Container解决,因此您无需手动创建new SomeUtility();或从容器IoC.Get<ISampleService>();拉出。

您可能也想知道:如果应要求创建SomeViewModel该怎么办,例如,当用户点击&#34;添加&#34;按钮?嗯,我很高兴你问。 :)对于这种情况,您可以使用工厂方法!

只需将其注册到容器中即可。

public class AppBootstrapper : BootstrapperBase
{
    protected override void Configure()
    {
        ...

        _container.Handler<IScreen>((x) => x.GetInstance<SomeViewModel>());
    }
}

现在,您可以轻松地将其注入构造函数,并根据需要使用它来创建SomeViewModel的任意数量的实例。

class ShellViewModel : Conductor<IScreen>.Collection.AllActive, IShell
{
    private Func<SomeViewModel> _vmFactory;

    public ShellViewModel(Func<SomeViewModel> vmFactory)
    {
        _vmFactory = vmFactory;
    }

    public void Add()
    {
        var newVM = _vmFactory();
        ActivateItem(newVM);
    }
}