2011-03-05 148 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(); 

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