Ninject с инициализаторами объектов и LINQ


Я новичок в 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 для Объекты или с инициализаторами объектов. Может быть, я ищу не там, где надо, но я уже целый день ищу, и все без толку.

Я подумывал о том, чтобы поместить ядро в синглетный экземпляр и посмотреть, сработает ли это, но я не уверен, что это будет, плюс я слышал, что передача вашего ядра-плохая вещь. В настоящее время я пытаюсь реализовать это в библиотеке классов. Если это невозможно, есть ли у кого-нибудь примеры или предложения относительно того, что является лучшей практикой разве в этом случае? Заранее спасибо за помощь.

Редактировать: Основываясь на некоторых ответах, я считаю, что должен уточнить. Да, приведенный выше пример кажется недолговечным, но это был просто пример одной части, которую я пытался сделать. Давайте представим себе более широкую картину. Скажем, вместо XML я собираю все свои данные через сторонний веб-сервис и создаю интерфейс для него, данные могут быть определенным объектом в wsdl или иногда это может быть строка xml. IPerson может быть используется как для объекта Person, так и для объекта User. Я буду делать это внутри отдельной библиотеки классов, потому что она должна быть переносимой и использоваться в других проектах, а передача ее в веб-приложение MVC3 и объекты будут использоваться также в javascript. Я ценю все ваши усилия до сих пор.

4 2

4 ответа:

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

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

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

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

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

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

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

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

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

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

Место, где вам в основном нужно использовать инициализаторы объектов, чтобы воспользоваться преимуществами linq, находится в методах, таких как GetPeople, где вы должны работать с конкретными классами, поэтому я считаю, что вы должны иметь лучшее из обоих миров. Нет, вы не сможете использовать инициализатор объекта в форме при работе с IPerson, но я не думаю, что вы если вы хотите использовать linq в методе GetPeople, то вам это когда-нибудь понадобится.

Edit: на самом деле вам не нужны инициализаторы объектов, чтобы использовать 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();

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