我正在使用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
的实例。
我如何获得实例?
答案 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
将获得SomeUtility
,SomeUtility
将获得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);
}
}