2014-01-23 44 views
1

我刚开始在我的wpf应用程序中使用Cliburn Micro。我开发使用依赖注入为了帮助保持抽象使用接口。使用Caliburn Micro依赖注入与自定义ModernUI ContentLoader

如何使用Caliburn Micros Bootstrappers容器来实例化我自己的类实例。

例如

public interface IFoo 
{ 
    int ReturnNumber(); 
} 

public class Foo : IFoo 
{ 
    public int ReturnNumber() 
    { 
     return 1; 
    } 
} 

public class SomeViewModel() 
{ 
    public SomeViewMode() 
    { 
     IFoo = //instance from caliburn 
    } 
} 

在我的引导程序我使用的是CompositionContainer中

---- ------ UPDATE

我使用现代的UI和卡利微构架侧但当引导程序试图解析包含IWindowManager参数的类型的实例时,引导程序在GetInstance(Type,String)方法中获取null值异常。我相信这是由于ModernUI采用View第一种方法使用内容加载器与Caliburn.Micro进行通信的性质所致,但是我正在努力寻找一种允许我的引导程序正常运行的解决方案。

这里是引导程序

public class AppBootstrapper : Bootstrapper<IShellViewModel> 
{ 
    private static CompositionContainer _container; 
    .... 

    protected override void Configure() 
    { 
     // Add New ViewLocator Rule 
     ViewLocator.NameTransformer.AddRule(
      @"(?<nsbefore>([A-Za-z_]\w*\.)*)?(?<nsvm>ViewModels\.)(?<nsafter>([A-Za-z_]\w*\.)*)(?<basename>[A-Za-z_]\w*)(?<suffix>ViewModel$)", 
      @"${nsbefore}Views.${nsafter}${basename}View", 
      @"(([A-Za-z_]\w*\.)*)?ViewModels\.([A-Za-z_]\w*\.)*[A-Za-z_]\w*ViewModel$" 
     ); 

     _container = new CompositionContainer(
       new AggregateCatalog(
       new AssemblyCatalog(typeof(IShellViewModel).Assembly), 
       AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>().FirstOrDefault() 
      ) 
     ); 

     var batch = new CompositionBatch(); 
     batch.AddExportedValue<IWindowManager>(new WindowManager()); 
     batch.AddExportedValue<IEventAggregator>(new EventAggregator()); 
     _container.Compose(batch); 
    } 

    protected override object GetInstance(Type serviceType, string key) 
    { 
     string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key; 

     var exports = _container.GetExportedValues<object>(contract); 
     return exports.FirstOrDefault(); 
    } 

我失去了一些东西明显的配置?

回答

1

你可以注入通过构造注射你的依赖(假设它是一个需要依赖):

public class SomeViewModel : Screen 
{ 
    private readonly IFoo foo; 

    public SomeViewModel(IFoo foo) 
    { 
     // Can use foo later, e.g. in OnActivate for your screen 
     this.foo = foo;    
    } 
} 

的Caliburn.Micro通用引导程序经由配置的容器解决了根视图模型(例如ShellViewModel)。如果SomeViewModelShellViewModel的依赖项,则它的所有依赖项都将由容器解析,并且还会解析任何进一步的链接依赖项。

如果您希望控制类型的生命周期,那么注入一个在您的容器中注册的工厂,并通过工厂创建该类型的新实例。

+0

您好我是建设注入了庞大的用户为使用了Ninject作为我过去的主要框架,但这个项目是使用ModernUI和卡利科技开发。只要我在ViewModel构造函数中不使用任何参数,我就有一个引导程序。使用参数,实例的任何ViewModel由Bootstrapper解析,但通过MUI内容加载Loader在Bootstrapper的GetInstance()方法中抛出一个exeption。任何想法为什么这可能是?我会在上面更新我的问题以示例,再次感谢。 – maxhap

+0

您可以创建一个使用Caliburn.Micro视图模型定位器(通过配置的容器解析视图模型)的自定义内容加载器。请参阅http://stackoverflow.com/questions/16421582/caliburn-micro-and-modernui-examples-tutorials。或者,您可能会考虑支持视图模型第一种方法的UI框架,例如MahApps.Metro - http://mahapps.com/MahApps.Metro/。 – devdigital

+0

我实际上使用的是自定义加载程序,几乎与该帖子相同(已经在过去查看过)。可悲的是使用MahApps不是一种选择。 – maxhap

1

好吧,我发现这个问题的解决方案,所以想我会发布它的任何其他人。通过诠释Caliburn.Micro寻找一个默认的构造函数,它不包含任何参数,但在类中不存在。因此需要使用[ImportingConstructor]属性来告诉caliburn micro使用注入填充参数来构建类的实例。

示例使用devdigitals例如

[ImportingConstructor] 
public class SomeViewModel : Screen 
{ 
    private readonly IFoo foo; 

    public SomeViewModel(IFoo foo) 
    { 
     // Can use foo later, e.g. in OnActivate for your screen 
     this.foo = foo;    
    } 
}