2

我是 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,而是通过第 3 方 Web 服务收集我的所有数据并为其创建接口,数据可能是 wsdl 中定义的对象,或者有时可能是 xml 字符串。IPerson 可用于 Person 对象和 User 对象。我将在一个单独的类库中执行此操作,因为它需要可移植并将用于其他项目,并将其交给 MVC3 Web 应用程序,并且对象也将在 javascript 中使用。到目前为止,我感谢所有输入。

4

4 回答 4

3

您的Person类是一个短暂的对象,它不适合用于依赖注入。除此之外,它不包含任何行为,只是一个 POCO(普通的旧 CLR 对象)。因为 POCO 不依赖于任何值得抽象的东西,所以通常没有理由抽象它们。换句话说:用给定的例子。你不需要IPerson接口。您可以在Person整个应用程序中直接使用该类。

但是,该GetPeople方法通常可以是您将使用 DI 配置抽象出来的服务的一部分。然而,包含该GetPeople(string xml)方法的服务接口可能是错误的抽象,因为这意味着您将始终提供一个 xml 字符串。当您拥有这个 XML 字符串时,是否有任何理由以任何其他方式解析该 XML 字符串?IPersonRepository有一个带有GetAllPeople()方法的接口会更方便。一个给定的实现可能是XmlPersonRepository使用 XML 数据源来获取人员(从磁盘、数据库或谁知道什么)。

于 2011-03-06T10:59:38.613 回答
2

你的IPerson接口有不止一种实现吗?(我对此表示怀疑,因为它似乎Person只是一个传递的数据对象。)也许我错过了你的问题的重点,但 DI 是为了分离关注点并将实现与接口设计抽象。

我看不到 DI 如何帮助您Person从定义的 XML 模式中提取对象。您正在解析数据,而不是动态注入实现。也许如果您想以不同的方式解析 XML 以比较性能,您将创建包含 的类的替代实现GetPeople,但我不认为这是您问题的重点。

于 2011-03-05T17:11:31.330 回答
1

Ninject 能为您做的就是为您提供 IPerson 的实现。它不会解析您的 XML 或其他结构。事实上,您很可能会丢失对象初始化语法,因为您必须通过 ninject 内核或服务定位器。

我会为你想要做的事情推荐一个序列化库。我会推荐 json.net 或.NET 的内置 XML 序列化

于 2011-03-05T21:27:24.813 回答
0

通常,我会简单地假设任何拥有 20k+ 代表的人可能比我对这些东西了解得更多。但是,在我看来,这也是:

1)您的示例与 Ninject 网站上使用的示例相差不远
2)即使“这个”特定示例不是一个好的示例,手头的问题是使用对象初始化器,这可能适用于任何其他数量的更多合法的场景。

不幸的是,我没有关于如何使用 Ninject 进行对象初始化的答案,但我确实有一个关于“在哪里”使用 Ninject 的建议,这可能会有所帮助(我意识到这篇文章已经有一年了,但也许这会对某人有所帮助) .

我同意您很可能应该在 GetPeople() 方法中使用具体类,因为该方法可能是特定于 Person 的实现的一部分(并且可能在同一个程序集和/或命名空间中)。但是,当您有类似表单的东西向用户展示有关 Person 的信息时,我应该认为它应该与 IPerson 一起使用,而不是具体的实现。

您主要需要使用对象初始化器以利用 linq 的地方是在像 GetPeople 这样的方法中,您应该使用具体的类,所以我相信您应该能够两全其美。不,在使用 IPerson 时,您将无法在表单中使用对象初始化程序,但我认为如果您想在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();

你可以看到如何修改它以很容易地与注入一起工作。

于 2012-02-21T03:59:00.147 回答