使用依赖注入返回用户定义的对象
Returning user defined objects using dependency injection
我正在使用 Ninject 进行依赖注入,并且在传递基本类型时我已经很好地工作了,但是我不确定在我开始传递自定义对象类型后构建应用程序的最佳方式.
这是一个简单的例子。我有 4 个项目:Main、Project A、Project B 和 Interfaces。主要参考项目 A、项目 B 和接口,项目 A 和项目 B 都参考接口。
在接口中,我定义了一个接口 IClassA,它有一个 return 是一个 int 的方法。
public interface IClassA
{
int ReturnFundamental();
}
在 ProjectA 中,我有实现 IClassA 的 ClassA。
public class ClassA : IClassA
{
public int ReturnFundamental()
{
return 1;
}
}
ProjectB 包含 ClassB,它接受 IClassA 作为基于构造函数的依赖注入。它还提供了一个方法,可以让我调用在IClassA中定义并在ClassA中实现的方法。
public class ClassB
{
private readonly IClassA classA;
public ClassB(IClassA classA)
{
this.classA = classA;
}
public void GetObject()
{
Console.WriteLine(classA.ReturnFundamental());
}
}
Main工程设置Ninject,绑定IClassA到ClassA,实例化ClassB实例,调用ClassB方法
static void Main(string[] args)
{
IKernel kernel = new StandardKernel();
kernel.Bind<IClassA>().To<ClassA>();
var classB = kernel.Get<ClassB>();
classB.GetObject();
Console.Read();
}
这一切都很好,ClassB 可以调用 ClassA 中的方法并 returned 值。但是,如果我不想 return 基本类型,而是想 return 我定义的自定义对象,最好的方法是什么?
如果我没记错的话,IClassA、ClassA 和 ClassB 都需要引用这个对象,并且在与 ClassA 或 ClassB 相同的项目中定义它会导致使用依赖注入来避免的耦合。
所以我能想到的唯一解决办法是:
声明接口项目中的所有对象
再创建一个项目,将所有用于接口间数据传递的对象放入。
创建一个新项目,其中包含 class 之间的单个交互所需的所有对象,其中每个交互都有它自己的项目,它引用包含它需要的所有对象。
我在第一个选项中看到的问题是,不清楚 classes 使用了哪些对象,我担心接口项目会变得太大,单个文件中包含太多信息位置。
第二个选项与第一个选项有相同的问题,因为它不清楚 classes 使用了哪些对象,但至少它将接口与仅用于传递数据的对象分开了。但是,它会在项目之间添加更多引用,因为(假设每个接口至少传递一个对象)每个接口和每个 class 实现该接口或使用该接口都需要对新项目的引用。
第三个选项至少明确了哪些 class 交互需要哪些对象,因为它们都组合在一起,但是这会导致创建大量项目。
我想有一个很好的解决方案,因为它一定是一个非常普遍的问题,但我不确定大型项目的最佳实施方式。
无需创建界面项目。
人们通常所做的是将实现 (-details) 声明为内部,将接口声明为 public。例如。
public class PersonInfo
{
string FirstName { get; set; }
string Surname { get; set; }
Address Address { get; set; }
}
public interface IPersonSearchService
{
IEnumerable<PersonInfo> Search(string keyword);
}
internal class PersonSearchService : IPersonSearchService
{
....
}
现在您添加一个 NinjectModule:
public class PersonSearchServiceModule : NinjectModule
{
public override void Load()
{
this.Bind<IPersonSearchService>().To<PersonSearchService>();
}
}
并在组合根目录(应用程序项目、主项目、.. whatchamacallit)中加载模块,通过 kernel.Load<PersonSearchServiceModule>()
或一个(或多个)程序集的所有 Module
显式加载模块kernel.Load(IEnumerable<Assembly>)
过载。
使用 Feature-Namespaces 也是一个好主意。
我正在使用 Ninject 进行依赖注入,并且在传递基本类型时我已经很好地工作了,但是我不确定在我开始传递自定义对象类型后构建应用程序的最佳方式.
这是一个简单的例子。我有 4 个项目:Main、Project A、Project B 和 Interfaces。主要参考项目 A、项目 B 和接口,项目 A 和项目 B 都参考接口。
在接口中,我定义了一个接口 IClassA,它有一个 return 是一个 int 的方法。
public interface IClassA
{
int ReturnFundamental();
}
在 ProjectA 中,我有实现 IClassA 的 ClassA。
public class ClassA : IClassA
{
public int ReturnFundamental()
{
return 1;
}
}
ProjectB 包含 ClassB,它接受 IClassA 作为基于构造函数的依赖注入。它还提供了一个方法,可以让我调用在IClassA中定义并在ClassA中实现的方法。
public class ClassB
{
private readonly IClassA classA;
public ClassB(IClassA classA)
{
this.classA = classA;
}
public void GetObject()
{
Console.WriteLine(classA.ReturnFundamental());
}
}
Main工程设置Ninject,绑定IClassA到ClassA,实例化ClassB实例,调用ClassB方法
static void Main(string[] args)
{
IKernel kernel = new StandardKernel();
kernel.Bind<IClassA>().To<ClassA>();
var classB = kernel.Get<ClassB>();
classB.GetObject();
Console.Read();
}
这一切都很好,ClassB 可以调用 ClassA 中的方法并 returned 值。但是,如果我不想 return 基本类型,而是想 return 我定义的自定义对象,最好的方法是什么?
如果我没记错的话,IClassA、ClassA 和 ClassB 都需要引用这个对象,并且在与 ClassA 或 ClassB 相同的项目中定义它会导致使用依赖注入来避免的耦合。
所以我能想到的唯一解决办法是:
声明接口项目中的所有对象
再创建一个项目,将所有用于接口间数据传递的对象放入。
创建一个新项目,其中包含 class 之间的单个交互所需的所有对象,其中每个交互都有它自己的项目,它引用包含它需要的所有对象。
我在第一个选项中看到的问题是,不清楚 classes 使用了哪些对象,我担心接口项目会变得太大,单个文件中包含太多信息位置。
第二个选项与第一个选项有相同的问题,因为它不清楚 classes 使用了哪些对象,但至少它将接口与仅用于传递数据的对象分开了。但是,它会在项目之间添加更多引用,因为(假设每个接口至少传递一个对象)每个接口和每个 class 实现该接口或使用该接口都需要对新项目的引用。
第三个选项至少明确了哪些 class 交互需要哪些对象,因为它们都组合在一起,但是这会导致创建大量项目。
我想有一个很好的解决方案,因为它一定是一个非常普遍的问题,但我不确定大型项目的最佳实施方式。
无需创建界面项目。 人们通常所做的是将实现 (-details) 声明为内部,将接口声明为 public。例如。
public class PersonInfo
{
string FirstName { get; set; }
string Surname { get; set; }
Address Address { get; set; }
}
public interface IPersonSearchService
{
IEnumerable<PersonInfo> Search(string keyword);
}
internal class PersonSearchService : IPersonSearchService
{
....
}
现在您添加一个 NinjectModule:
public class PersonSearchServiceModule : NinjectModule
{
public override void Load()
{
this.Bind<IPersonSearchService>().To<PersonSearchService>();
}
}
并在组合根目录(应用程序项目、主项目、.. whatchamacallit)中加载模块,通过 kernel.Load<PersonSearchServiceModule>()
或一个(或多个)程序集的所有 Module
显式加载模块kernel.Load(IEnumerable<Assembly>)
过载。
使用 Feature-Namespaces 也是一个好主意。