Ninject с инициализаторами объектов и LINQ - PullRequest
2 голосов
/ 05 марта 2011

Я новичок в 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 я собираю все свои данные через сторонний веб-сервис и создаю для него интерфейс, данные могут быть определенным объектом в wsdl или иногда могут быть строкой xml.IPerson может использоваться как для объекта Person, так и для объекта User.Я буду делать это внутри отдельной библиотеки классов, потому что она должна быть переносимой и будет использоваться в других проектах, а также передавать ее в веб-приложение MVC3, и объекты также будут использоваться в javascript.Я ценю весь вклад до сих пор.

Ответы [ 4 ]

3 голосов
/ 06 марта 2011

Ваш класс Person является недолговечным объектом, и он плохо подходит для использования для внедрения зависимостей. Кроме того, он не содержит никакого поведения и является просто POCO (простым старым объектом CLR). Поскольку POCO не зависят ни от чего заслуживающего абстрагирования, обычно нет причин абстрагировать их. Другими словами: с приведенным примером. вам не нужен IPerson интерфейс. Вы можете работать напрямую с классом Person во всем приложении.

Однако метод GetPeople обычно может быть частью службы, которую вы бы абстрагировали, используя конфигурацию DI. Однако интерфейс службы, который содержит метод GetPeople(string xml), вероятно, будет неправильной абстракцией, поскольку это означает, что вы всегда предоставляете строку xml. Когда у вас есть эта XML-строка, будет ли какая-либо причина когда-либо анализировать эту XML-строку любым другим способом? Было бы удобнее иметь интерфейс IPersonRepository с методом GetAllPeople(). Данная реализация может быть XmlPersonRepository, которая использует источник данных XML для извлечения людей (с диска, из базы данных или кто знает что).

2 голосов
/ 05 марта 2011

Есть ли у вас более одной реализации вашего IPerson интерфейса? (Я сомневаюсь в этом, поскольку кажется, что Person - это просто объект данных, который передается.) Возможно, я упускаю суть вашего вопроса, но DI предназначен для отделения проблем и абстрагирования реализации от дизайна интерфейса.

Я не понимаю, как DI может помочь вам извлечь Person объект из определенной XML-схемы. Вы анализируете данные, а не внедряете реализацию динамически. Возможно, если бы вы хотели проанализировать XML другим способом для сравнения производительности, вы бы создали альтернативные реализации класса, содержащего GetPeople, но я не рассматриваю это как точку вашего вопроса.

1 голос
/ 06 марта 2011

Все, что Ninject может сделать для вас, - это предоставить вам реализацию IPerson. Он не будет анализировать ваш XML или другую структуру. Фактически, вы, скорее всего, потеряете синтаксис инициализации объекта, поскольку вам придется пройти через ядро ​​ninject или локатор службы.

Я бы предложил библиотеку сериализации для того, что вы хотите сделать. Я бы порекомендовал json.net или .NET встроенную сериализацию XML

0 голосов
/ 21 февраля 2012

Обычно, я бы просто предположил, что кто-то с 20k + rep здесь, вероятно, знает больше, чем я об этом. Однако мне также кажется, что:

1) Ваш пример не слишком далек от примеров, используемых на веб-сайте Ninject
2) Даже если этот «конкретный» пример не очень хороший, проблема заключается в использовании инициализаторов объектов, которые могут применяться к любому другому числу более законных сценариев.

К сожалению, у меня нет ответа о том, как выполнить инициализацию объекта с помощью Ninject, но у меня есть предложение о том, «где» использовать Ninject, которое может помочь (и я понимаю, что этому посту год, но, возможно, так и будет помогите кому-нибудь).

Я согласен, что вам, скорее всего, следует использовать конкретные классы в методе GetPeople (), поскольку этот метод, вероятно, является частью реализации, специфичной для Person (и, вероятно, в той же сборке и / или пространстве имен). Однако, когда у вас есть что-то вроде формы, которая представляет пользователю информацию о 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();

И вы можете видеть, как это можно легко изменить, чтобы работать с инъекцией.

...