我是Ninject的新手,所以我正在尝试甚至不可能,但我想问。我在下面自由交配,所以可能会有错别字。假设我有一个界面:
public interface IPerson
{
string FirstName { get; set; }
string LastName { get; set;}
string GetFullName();
}
具体:
public class Person : IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string GetFullName()
{
return String.Concat(FirstName, " ", LastName);
}
}
当我从数组或xml中检索数据时,我习惯做的就是这样:
public IEnumerable<IPerson> GetPeople(string xml)
{
XElement persons = XElement.Parse(xml);
IEnumerable<IPerson> people = (
from person in persons.Descendants("person")
select new Person
{
FirstName = person.Attribute("FName").Value,
LastName = person.Attribute("LName").Value
}).ToList();
return people;
}
我不想以这种方式将混凝土紧密地耦合到界面。我无法找到任何关于将Ninject与LINQ to Objects或对象初始化器一起使用的信息。我可能正在寻找错误的地方,但我一直在寻找一天没有运气。
我正在考虑将内核放入单例实例并查看是否可行,但我不确定它是否会加上我听说传递内核是一件坏事。我正在尝试在目前的类库中实现它。如果这是不可能的,那么在这种情况下,是否有人有任何关于最佳实践的例子或建议?在此先感谢您的帮助。
修改 基于一些答案,我觉得我应该澄清一下。是的,上面的例子似乎很短暂,但它只是我试图做的一件事的一个例子。让我们来看一个更大的图景。说而不是XML我通过第三方Web服务收集我的所有数据,并且我正在为它创建一个接口,数据可以是wsdl中的已定义对象,或者有时可能是xml字符串。 IPerson可以用于Person对象和User对象。我将在一个单独的类库中执行此操作,因为它需要是可移植的,并将在其他项目中使用,并将其交给MVC3 Web应用程序,并且这些对象也将在javascript中使用。到目前为止,我很欣赏所有的意见。
答案 0 :(得分:3)
你的Person
类是一个短暂的对象,它不适合用于依赖注入。除此之外,它不包含任何行为,只是一个POCO(普通的旧CLR对象)。因为POCO不依赖于任何值得抽象的东西,所以通常没有理由抽象它们。换句话说:用给定的例子。您不需要IPerson
界面。您可以在整个申请过程中直接使用Person
课程。
GetPeople
方法通常可以是您使用DI配置抽象出来的服务的一部分。但是,包含GetPeople(string xml)
方法的服务接口可能是一个错误的抽象,因为这意味着您将始终提供一个xml字符串。当你有这个XML字符串时,是否有任何理由以任何其他方式解析该XML字符串?使用IPersonRepository
方法建立GetAllPeople()
接口会更方便。给定的实现可以是XmlPersonRepository
,它使用XML数据源来获取人员(从磁盘,数据库或谁知道什么)。
答案 1 :(得分:2)
您的IPerson
界面是否有多个实现? (我怀疑它,因为Person
似乎只是一个传递的数据对象。)也许我错过了你的问题的重点,但DI是用于分离关注点和从接口设计中抽象实现。
我不知道DI如何帮助您从定义的XML模式中提取Person
对象。您正在解析数据,而不是动态注入实现。也许如果你想用不同的方式来解析XML以比较性能,你可以创建包含GetPeople
的类的替代实现,但我不认为这是你的问题的重点。
答案 2 :(得分:1)
所有Ninject可以为你做的就是让你实现IPerson。它不会解析您的XML或其他结构。实际上,您很可能会丢失对象初始化语法,因为您必须通过ninject内核或服务定位器。
我建议你做一个序列化库来做你想做的事情。我会推荐json.net或.NET's built in XML serialization
答案 3 :(得分:0)
通常,我只是假设任何拥有20k + rep的人可能比我对这些东西的了解更多。但是,在我看来:
1)您的示例与Ninject网站上使用的示例相差不多 2)即使'这个'特定的例子不是一个好的例子,手头的问题是使用对象初始化器,并且可以适用于任何其他数量的更合理的场景。
不幸的是我没有关于如何使用Ninject进行对象初始化的答案,但我确实有一个关于'在哪里'使用Ninject可能有帮助的建议(我意识到这篇文章已经有一年了但也许这会帮助某人)。
我同意您最有可能在GetPeople()方法中使用具体类,因为该方法可能是特定于Person的实现的一部分(并且可能在同一个程序集和/或命名空间中)。但是,当你有一个类似于向用户提供关于某个人的信息的表格时,我应该认为它应该与IPerson合作而不是具体的实现。
你主要需要使用对象初始化器才能利用linq的地方虽然是像GetPeople这样的方法,你应该使用具体的类,但我相信你应该能够兼顾两个世界的优点。不,你在使用IPerson时无法在表单中使用对象初始化程序,但我不认为你需要以这种方式需要,如果你想使用linq GetPeople方法。
编辑:实际上你并不需要'对象初始化器来使用linq
如果你放弃一些语法糖,你可以重写
IEnumerable<IPerson> people = (
from person in persons.Descendants("person")
select new Person
{
FirstName = person.Attribute("FName").Value,
LastName = person.Attribute("LName").Value
}).ToList();
作为
IEnumerable<IPerson> people =
(persons.Descendants("person")
.Select(o =>
{
var p = new Person();
p.FirstName = person.Attribute("FName").Value;
p.LastName = person.Attribute("LName").Value;
return p;
}).ToList();
你可以很容易地看到如何修改它以便与注射配合使用。