我正在使用卡利伯恩微型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的实例。
我怎样才能得到这个实例?
发布于 2015-04-24 07:26:24
我假设你在Caliburn.Micro中使用MEF
这样你就可以这样得到一个实例:
SampleService service = IoC.Get<ISampleService>();希望这能帮到你。
发布于 2015-04-24 09:22:56
Guerudo的答案是有效的,但是除非您必须使用IoC.Get<>,否则您永远不应该使用它。使用服务定位器被认为是反模式。
获取实例的正确时间是使用构造函数注入。假设你有一个MainViewModel,做这个
public class MainViewModel
{
private readonly ISampleService _sampleService;
public MainViewModel(ISampleService sampleService)
{
_sampleService = sampleService
}
}并在您的_sampleService中的任何地方使用ViewModel。
而且不需要任何带有Caliburn.Micro的MEF属性。
发布于 2015-04-24 10:42:59
在大多数情况下,您应该避免直接从容器中取出东西。相反,考虑使用依赖注入。
例如,如果您想在SomeUtility类中使用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。所有这些都将由容器解决,因此您不需要手动创建new SomeUtility();或从容器IoC.Get<ISampleService>();中提取。
另外,您可能想知道:如果应该根据请求创建SomeViewModel,例如,当用户单击"Add“按钮时怎么办?我很高兴你问了。)在这种情况下,您可以使用工厂方法!
把它登记到容器里就行了。
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);
}
}https://stackoverflow.com/questions/29840272
复制相似问题