我有一个接口,由我的所有类实现,负责将数据导出为不同的格式。
示例代码:
public interface IExport
{
string Exporter();
}
public class ExcelExport : IExport
{
public string Exporter()
{
return "excel";
}
}
public class PdfExport : IExport
{
public string Exporter()
{
return "pdf";
}
}
我想在运行时获得一个特定类型,所以我知道我必须使用抽象工厂,但我不知道在这个例子中是怎么回事。
导出由经理类处理:
public interface IExportManager
{
IExport GetExportProvider(ExportType type);
}
public interface IExportFactory
{
IExport CreateExport(ExportType type);
}
public class ExportManager : IExportManager
{
private IExportFactory exportFactory;
public ExportManager(IExportFactory exportFactory)
{
this.exportFactory = exportFactory;
}
public IExport GetExportProvider(ExportType type)
{
return exportFactory.CreateExport(type);
}
}
public enum ExportType
{
PDF,
XLSX
}
如何使用GetExportProvider方法根据类型参数获取正确的对象实例?
这是我的Ninject模块:
public class NinModule : NinjectModule
{
public override void Load()
{
this.Bind<IExportFactory>().ToFactory();
this.Bind<IExportManager>().To<ExportManager>();
this.Bind<IExport>().To<ExcelExport>();//.WhenInjectedInto<IExportManager>().WithPropertyValue("type", ExportType.XLSX);
this.Bind<IExport>().To<PdfExport>();//.WhenInjectedInto<IExportManager>().WithPropertyValue("type", ExportType.PDF);
}
}
用于测试它的代码:
static void Main(string[] args)
{
IKernel k = new StandardKernel(new NinModule());
IExportManager r = k.Get<IExportManager>();
var pdf = r.GetExportProvider(ExportType.PDF);
Console.WriteLine(pdf.Exporter());
Console.Read();
}
提前感谢您的帮助。
答案 0 :(得分:0)
我对Ninject一无所知,但严格来说,从C#的角度来看,为什么不能这样做......
public class ExportFactory : IExportFactory
{
public IExport CreateExport(ExportType type)
{
switch(type)
{
case ExportType.PDF:
return new PdfExport();
case ExportType.XLSX
return new ExcelExport();
}
}
}
答案 1 :(得分:0)
我认为您需要在ExportFactory类中创建动态绑定。 像这样:
if (exportType == ExportType.PDF)
{
Bind<IExport>().To<PdfExport>().InRequestScope();
}
else if (exportType == ExportType.XLSX)
{
Bind<IExport>().To<ExcelExport>().InRequestScope();
}
答案 2 :(得分:0)
好吧,最后我得到了解决方案。
一种可能性是创建自定义提供程序:
public class ExportProvider : Provider<IExport>
{
protected override IExport CreateInstance(IContext context)
{
ExportType type = (ExportType)context.Parameters.First().GetValue(context, null);
switch (type)
{
case ExportType.PDF: return new PdfExport();
case ExportType.XLSX: return new ExcelExport();
}
return null;
}
}
并配置:this.Bind<IExport>().ToProvider<ExportProvider>();
我找到的第二种可能性:
this.Bind<IExport>().To<ExcelExport>().When((q) =>
{
ExportType type = (ExportType)q.Parameters.First().GetValue(new DummyContext(), null);
return type == ExportType.XLSX;
});
this.Bind<IExport>().To<PdfExport>().When((q) =>
{
ExportType type = (ExportType)q.Parameters.First().GetValue(new DummyContext(), null);
return type == ExportType.PDF;
});
IParameter的GetValue要求不提供空IContext。在When子句中我们不能得到任何,但是我们可以使用不同的,因为在方法中没有检查这个参数。因此,我们可以创建一个实现IContext接口的简单类:
public class DummyContext : IContext
{
public Ninject.Planning.Bindings.IBinding Binding
{
get { throw new NotImplementedException(); }
}
public Type[] GenericArguments
{
get { throw new NotImplementedException(); }
}
public IProvider GetProvider()
{
throw new NotImplementedException();
}
public object GetScope()
{
throw new NotImplementedException();
}
public bool HasInferredGenericArguments
{
get { throw new NotImplementedException(); }
}
public IKernel Kernel
{
get { throw new NotImplementedException(); }
}
public ICollection<IParameter> Parameters
{
get { throw new NotImplementedException(); }
}
public Ninject.Planning.IPlan Plan
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public IRequest Request
{
get { throw new NotImplementedException(); }
}
public object Resolve()
{
throw new NotImplementedException();
}
}