C# 当Ninject中的上下文相同时,解决多个服务绑定的更好方法?
我有一个类,它有一个工厂方法,当它发现自己的序列化版本时,应该返回它;否则,它应返回自身的新实例:C# 当Ninject中的上下文相同时,解决多个服务绑定的更好方法?,c#,dependency-injection,ninject,inversion-of-control,C#,Dependency Injection,Ninject,Inversion Of Control,我有一个类,它有一个工厂方法,当它发现自己的序列化版本时,应该返回它;否则,它应返回自身的新实例: class ClassToDeserialize : List<SomeClass> { public static event Func<ClassToDeserialize> onNoDeserializationFile; public ClassToDeserialize(SomeClass firstInList) { t
class ClassToDeserialize : List<SomeClass>
{
public static event Func<ClassToDeserialize> onNoDeserializationFile;
public ClassToDeserialize(SomeClass firstInList)
{
this.Add(firstInList);
}
public static ClassToDeserialize DeserializeIfAny(string jsonPath)
{
if (File.Exists(jsonPath))
return JsonConvert.DeserializeObject<ClassToDeserialize>(File.ReadAllText(jsonPath));
return onNoDeserializationFile();
}
}
ClassToDeserialize类:列表
{
公共静态事件函数onNoDeserializationFile;
公共类进行序列化(SomeClass firstInList)
{
这个.Add(firstInList);
}
public static ClassToDeserialize反序列化任意(字符串jsonPath)
{
if(File.Exists(jsonPath))
返回JsonConvert.DeserializeObject(File.ReadAllText(jsonPath));
返回onNoDeserializationFile();
}
}
我正在尝试重构我的应用程序以使用DI,但问题是我必须对类进行双重绑定以进行序列化,如下所示:
static void Main(string[] args)
{
string json = @"C:\obj_serialized.txt";
IKernel ninjectKernel = new StandardKernel();
ClassToDeserialize.onNoDeserializationFile += (() => ninjectKernel.Get<ClassToDeserialize>("NoSerialization"));
ninjectKernel.Bind<ClassToDeserialize>().ToSelf().Named("NoSerialization").WithConstructorArgument("jsonPath", json);
ninjectKernel.Bind<ClassToDeserialize>().ToConstant<ClassToDeserialize>(ClassToDeserialize.DeserializeIfAny(json));
}
static void Main(字符串[]args)
{
字符串json=@“C:\obj_serialized.txt”;
IKernel ninjectKernel=新的标准内核();
ClassToDeserialize.onNoDeserializationFile+=(()=>ninjectKernel.Get(“NoSerialization”);
ninjectKernel.Bind().ToSelf().Named(“NoSerialization”)。带有构造函数参数(“jsonPath”,json);
ninjectKernel.Bind().ToConstant(ClassToDeserialize.DeserializeIfAny(json));
}
我添加了onNoDeserializationFile事件,让ninject处理所有实例化,并将我的业务逻辑与IoC分离,然后我打算获得一个依赖于ClassToDeserialize的服务,为了能够解决这个请求,我需要找到一种方法告诉ninject,当找到序列化文件时,它应该调用相应的绑定(即使上下文相同)
ninjectKernel.Get().DoSomething();
我知道这类似于服务定位器反模式,但不是我使用容器的唯一方式,而且这种行为仅与我的应用程序的入口点相关
解决这个问题的正确方法是什么?您可以将决策逻辑放入一个 另外还有条件的
When
绑定语法。看
如何使用:
kernel.Bind<ClassToDeserialize>().ToSelf()
.WithConstructorArgument(...); // default binding
kernel.Bind<ClassToDeserialize>()
.ToMethod(ctx => JsonConvert.DeserializeObject<ClassToDeserialize>(...))
.InSingletonScope()
.When(ctx => File.Exists(...));
kernel.Bind().ToSelf()
.带有构造函数参数(…);//默认绑定
kernel.Bind()
.ToMethod(ctx=>JsonConvert.DeserializeObject(…)
.InSingletonScope()
.When(ctx=>File.Exists(…);
(提示:我没有编译它,所以方法序列可能有点偏离)。您的
ClassToDeserialize
似乎是一个DTO。不应在容器中注册DTO、实体、消息和其他包含数据的类。容器用于分解组件;具有行为的类。任何时候,当您试图混合数据和行为并将其注册到您的容器中时,事情都会出错。所以数据类不应该有依赖关系。它们应该简单地通过使用容器解析的对象图进行“推送”。您应该相应地重构代码,这样做会解决很多问题。@Steven也许您是对的,但我认为DTO是我的-SomeClass
class。每当我从列表中添加或删除一些类时,我都会将类作为自定义列表来进行序列化!谢谢,这正是我所需要的,我确实看到了上下文绑定文档,但我忽略了这一点,我不知道上下文绑定可以如此具体。我试着给你的答案打个比方,但我显然是新来的,现在还做不到:/
kernel.Bind<ClassToDeserialize>().ToSelf()
.WithConstructorArgument(...); // default binding
kernel.Bind<ClassToDeserialize>()
.ToMethod(ctx => JsonConvert.DeserializeObject<ClassToDeserialize>(...))
.InSingletonScope()
.When(ctx => File.Exists(...));