2011-03-05 75 views
2

我是Ninject的新手,所以我想尝试甚至不可能,但我想问。我自由处理下面的内容,所以可能会出现拼写错误。比方说,我有一个接口:Ninject与对象初始化器和LINQ

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

关于您的更新,我仍然不认为你需要的接口。在您编辑时描述的情况下,您需要围绕第三方Web服务进行抽象,以了解如何将从服务返回的对象转换为新的Person对象。 'Person'只是一个POCO域对象,通常在整个应用程序中重用。 – Steven 2011-03-07 16:18:26

回答

3

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

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

+0

感谢所有的投入史蒂芬,我相信我误解了它的使用,并且我已经摆脱这样做。我现在只是在工厂使用它,并在适当情况下使用一些注入资产。 – 2011-03-07 21:51:16

+0

@亚历山大:不客气。 – Steven 2011-03-07 21:59:52

2

您是否有多个实现您的IPerson接口? (我怀疑它,因为Person似乎只是一个传递的数据对象。)也许我错过了您的问题的重点,但DI是用于分离关注点并从界面设计中抽象实现。

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

1

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

我会建议一个你想做的序列化库。我会推荐json.net或.NET's built in XML serialization

+0

ryber,感谢您的建议,但我不找Ninject解析XML,而我在寻找它提供的依赖关系,而不是人选择新的人。 – 2011-03-07 16:13:30

0

通常情况下,我只想在这里承担与20K +推销员的人可能知道的比我多过这样的事。然而,它也似乎我说:

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(); 

你可以很容易地看到如何修改以适应注射。