我可以使用MEF来组合具有不同构造函数参数的同一类型的几个项吗
本文关键字:类型 几个 构造函数 MEF 可以使 组合 我可以 参数 | 更新日期: 2023-09-27 18:21:27
我有以下接口定义的
IOne
ITwo
IThree
ICalcalculator
并且有几个的实现
ClassOne: IOne
ClassTwo: IOne
ClassThree : ITwo
ClassFour : ITwo
ClassFive: IThree
MyCalc : ICalculator
MyCalc需要类1-4,但是ClassOne
和ClassThree
的2个实例区别为初始化,即
public MyCalc(){
ClassOne first= new ClassOne("filePath1");
ClassOne second = new ClassOne("filePath2");
ClassThree third = new ClassThree ("filePath3");
ClassThree fourth = new ClassThree ("filePath4");
}
我正在尝试使用MEF来创建构造MyCalc。在上面的示例中,filePathX
将位于配置文件中。到目前为止,我已经做了以下几项工作,似乎奏效了,但我觉得我目前的方法和方法是不正确的。考虑到这种方法,我将自己与名称(ValDatePrices和EDDatePrices)绑定在一起,它并不比我目前的方法更干净(见上文)。
有没有一种更干净的方法来加载具有不同ctor参数的同一类型的多个对象?
public class MyCalc: ICalculator
{
private CompositionContainer container;
public MyCalc()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(typeof(MyCalc).Assembly));
container = new CompositionContainer(catalog);
try
{
this.container.ComposeExportedValue<ClassFive>(
new ClassFive((ConfigurationManager.AppSettings["SomePath"])));
this.container.ComposeExportedValue<ClassOne>(
"ValDatePrices"
, new ClassOne((ConfigurationManager.AppSettings["filePath1"])));
this.container.ComposeExportedValue<ClassOne>(
"EDDatePrices"
, new ClassOne((ConfigurationManager.AppSettings["filePath2"])));
this.container.ComposeParts(this);
}
catch (CompositionException compositionException)
{
Console.WriteLine(compositionException.ToString());
}
}
[Import("ValDatePrices")]
public ClassOne ValDatePrices;
[Import("EDDatePrices")]
public ClassOne EDDatePrices;
[Import]
public ClassFive SPointReader;
public void Calculate()
{
Console.WriteLine(SPointReader.Result);
Console.WriteLine(ValDatePrices.Result.Count);
Console.WriteLine(EDDatePrices.Result.Count);
Console.ReadKey();
}
}
用法
class Program
{
static void Main(string[] args)
{
var p = new MyCalc();
p.Calculate();
}
}
}
附带问题:MyCalc
构造函数中的代码应该位于哪里
您是否考虑过使用合适的DI/IoC容器?这可以通过使用例如NInject或StructureMap以干净的方式轻松实现。
以下是如何使用NInject。注意,有很多方法可以做到这一点,你应该看看他们的教程,让NInject适合你的需要。
MyCalculator
public class MyCalculator : ICalculator
{
private IOne _oneFirst;
private IOne _oneSecond;
private ITwo _twoFirst;
private ITwo _twoSecond;
private IThree _three;
public MyCalculator([Named("Val")] IOne oneFirst, [Named("ED")] IOne oneSecond,
[Named("Val")] ITwo twoFirst, [Named("ED")] ITwo twoSecond, IThree three)
{
_oneFirst = oneFirst;
_oneSecond = oneSecond;
_twoFirst = twoFirst;
_twoSecond = twoSecond;
_three = three;
}
public void Calculate()
{
}
}
内核
public class CalculatorModule : NinjectModule
{
public override void Load()
{
Bind<IOne>().ToMethod(CreateOne).Named("Val");
Bind<IOne>().ToMethod(CreateTwo).Named("ED");
Bind<ITwo>().ToMethod(CreateThree).Named("Val");
Bind<ITwo>().ToMethod(CreateFour).Named("ED");
Bind<IThree>().To<ClassFive>();
Bind<ICalculator>().To<MyCalculator>();
}
private ITwo CreateFour(IContext arg)
{
return new ClassFour();
}
private ITwo CreateThree(IContext arg)
{
return new ClassThree();
}
private IOne CreateOne(IContext context)
{
return new ClassOne("filePath1");
}
private IOne CreateTwo(IContext arg)
{
return new ClassTwo("filePath2");
}
}
关于内核的注意:如果您愿意,可以将方法缩短为lambda函数,并且可以用参数名称或自定义属性替换命名属性。参见上下文绑定
用法
class Program
{
static void Main(string[] args)
{
StandardKernel kernel = new StandardKernel(new CalculatorModule());
var cal = kernel.Get<ICalculator>();
cal.Calculate();
}
}