альтернативы внедрения зависимости

Скорее всего, это происходит из-за np.nan где-то во входных данных. Пример этого показан ниже -

In [1]: A = np.array([4, 2, 1])

In [2]: B = np.array([2, 2, np.nan])

In [3]: A<=B
RuntimeWarning: invalid value encountered in less_equal
Out[3]: array([False,  True, False], dtype=bool)

. Для всех этих сравнений с участием np.nan он выводит False. Подтвердим это для сравнения broadcasted . Вот пример -

In [1]: A = np.array([4, 2, 1])

In [2]: B = np.array([2, 2, np.nan])

In [3]: A[:,None] <= B
RuntimeWarning: invalid value encountered in less_equal
Out[3]: 
array([[False, False, False],
       [ True,  True, False],
       [ True,  True, False]], dtype=bool)

Обратите внимание на третий столбец на выходе, который соответствует сравнению с третьим элементом np.nan в B, и это приводит ко всем значениям False.

14
задан terjetyl 11 December 2008 в 12:06
поделиться

11 ответов

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

, Таким образом, мой класс коммерческих продуктов был бы похож:

public class BusinessProducts
{
     private IDataContextFactory DataContextFactory { get; set; }  // my interface

     public BusinessProducts() : this(null) {}

     public BusinessProducts( IDataContextFactory factory )
     {
          this.DataContext = factory ?? new BusinessProductsDataContextFactory();
     }

     public void DoSomething()
     {
          using (DataContext dc = this.DataContextFactory().CreateDataContext())
          {
             ...
          }
     }

альтернатива этому должна была бы сделать свойство фабрики публично устанавливаемым и ввести альтернативную фабрику путем установки свойства. Так или иначе, если Вы захотите сохранить пустого конструктора, то необходимо будет обеспечить значение по умолчанию.

9
ответ дан 1 December 2019 в 08:20
поделиться

Можно создать фабрику. Контейнеры DI являются лучшими для проводок, которые происходят во время установки - не во времени выполнения (Поскольку это надеется быть случаем). Фабрики могут быть реализованы по-разному, в зависимости от того, насколько сменный это должно быть, и сколько мест необходимо использовать его.

6
ответ дан 1 December 2019 в 08:20
поделиться

У меня обычно был бы пустой конструктор, который использует твердый экземпляр (или экземпляры, созданные МОК), AMD один с DI. т.е.

public class BusinessProducts
{
   IDataContext _dx;

   BusinessProducts()
   {
      _dx = new SolidDataContext();
   }

   BusinessProducts(IDataContext dx)
   {
      _dx = dx;
   }
}

Этот путь можно использовать DI для переопределения экземпляра по умолчанию в тестировании поблочного тестирования.

6
ответ дан 1 December 2019 в 08:20
поделиться

Ваши чувства, в то время как допустимый, неуместны.

Шаблон Внедрения зависимости является прямым приложением Инверсии принципа Управления.

Это означает, что, вместо Вашего класса, управляющего экземплярами других классов, использует, что отношения инвертируются, и зависимости предоставляются ему.

По сути, Ваши классы естественно выставляют свои зависимости через аргументы конструктора или свойства. Проявление презрения к этой структуре говорит, что у Вас нет действительно grokked шаблона.

4
ответ дан 1 December 2019 в 08:20
поделиться

Здесь существует два отличных случая:

В производственном коде Вы будете никогда запись

new BusinessProducts(dataContextImplementation)

, потому что внедрение зависимости будет обычно создавать полную иерархию объектов для Вас. Это - "вирусная" природа шаблонов внедрения зависимости, они имеют тенденцию принимать полный контроль над Вашим сервисным созданием.

В коде модульного теста Вы будете обычно создавать это сами, но довольно часто Вы будете предоставлять фиктивный объект или тупиковую реализацию dataContextImplementation. Таким образом, обычно Вы будете вводить объект, который не имеет большого количества последующих зависимостей.

3
ответ дан 1 December 2019 в 08:20
поделиться

Обычно сама платформа будет иметь логику для создания всего дерева объектов. Например, вместо

new SomeObjectO(diContext)

Вы назвали бы платформу как это:

DIFramework.GetNew<SomeObjectO>();

или

DIFramework.Get<SomeObject>();

Другая интересная платформа для взгляда на то, если требуется узнать о DI и процессе, является Единицей Microsoft и Объектными проектами Разработчика.

1
ответ дан 1 December 2019 в 08:20
поделиться

Если Вам действительно не нравится вводить этот экземпляр в конструкторе, Вы могли бы попытаться использовать CommonServiceLocator с Вашей любимой совместимой.NET depedency инжекционная платформа. Это позволило бы Вам писать код как это:

public class BusinessProducts
{
   IDataContext _dx;

   BusinessProducts()
   {
      _dx = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IDataContext>();
   }

   public List<Product> GetProducts()
   {
    return dx.GetProducts();
   }
}

Однако остерегайтесь этого, это не то, что ожидало бы большинство людей, когда они знают, что Вы используете платформу внедрения зависимости. Я думаю, что намного более распространено использовать платформу внедрения зависимости и разрешение этому создать все объекты для Вас.

BusinessProducts bp = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<BusinessProducts>();

, Если требуется избежать, dependeny инжекционный путь платформы, с помощью фабрики является, вероятно, лучшим способом пойти.

1
ответ дан 1 December 2019 в 08:20
поделиться

Существует техника, названная DI бедного человека, который похож на это

public class BusinessProducts
{
   IDataContext _dx;

   BusinessProducts() : this(new DataContext()) {}

   BusinessProducts(IDataContext dx)
   {
      _dx = dx;
   }

   public List<Product> GetProducts()
   {
    return dx.GetProducts();
   }
}

Это не идеально, так как это связывает Вас с реализацией, но это - хорошая стартовая площадка к отделенному коду. это подобно @tvanfosson, но много simplier.

Я второй рекомендация для Виндзора

1
ответ дан 1 December 2019 в 08:20
поделиться

можно также посмотреть Виндзор для МОК.

0
ответ дан 1 December 2019 в 08:20
поделиться

http://springframework.net/ и http://structuremap.sourceforge.net/Default.htm является, вероятно, главным образом используемыми платформами DI для основанных на.NET языков и оба сделает то, в чем Вы нуждаетесь.

1
ответ дан 1 December 2019 в 08:20
поделиться

Мой код сошлется на Microsoft Unity, но я уверен, что это довольно применимо ко всем платформам DI. При использовании DI правильно, Вы никогда не должны называть новый BusinessObject (новый dataContext), ассоциация DI обработает все это для Вас.

Мой пример будет немного давно, я вставлю в некотором коде, я использую для выполнения Образцового веб-сайта Предъявителя Представления полностью DI, загруженный Единицей. (Если Вы хотите полный исходный выезд мой блог и загружаете его с моего сервера Assembla SVN),

Загрузитесь контейнер (может быть в коде как, я предпочитаю или конфигурация использования),

protected void Application_Start(object sender, EventArgs e)
{
    Application.GetContainer()
        // presenters / controllers are per request                 
        .RegisterType<IEmployeeController, EmployeeController>(new ContextLifetimeManager<IEmployeeController>())

        //Data Providers are Per session                
        .RegisterType<IEmployeeDataProvider, EmployeeDataProvider>(new SessionLifetimeManager<IEmployeeDataProvider>())

        //Session Factory is life time
        .RegisterType<INHibernateSessionManager, NHibernateSessionManager>(new ContainerControlledLifetimeManager());
}

Пользовательский HTTP-модуль называет Метод кумулятивного построения Единицы для каждой страницы во время вызова OnPreRequest.

private static void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
    var handler = HttpContext.Current.Handler;
    HttpContext.Current.Application.GetContainer().BuildUp(handler.GetType(), handler);

    // User Controls are ready to be built up after the page initialization is complete
    var page = HttpContext.Current.Handler as Page;
    if (page != null)
    {
        page.InitComplete += OnPageInitComplete;
    }
}

Предъявитель контейнера страницы украшен [Зависимостью] атрибут

public partial class Employees : Page, IEmployeeView
{
    private EmployeePresenter _presenter;

    [Dependency]
    public EmployeePresenter Presenter
    {
        set
        {
            _presenter = value;
            _presenter.View = this;
        }
    }
}

Предъявитель с методом InjectionConstructor

public class EmployeePresenter : Presenter<IEmployeeView>
{
    private readonly IEmployeeController _controller;

    [InjectionConstructor]
    }
    public EmployeePresenter(IEmployeeController controller)
    {
        _controller = controller;
}

Контроллер следует примеру

public class EmployeeController : IEmployeeController
{
    private readonly IEmployeeDataProvider _provider;

    [InjectionConstructor]
    public EmployeeController(IEmployeeDataProvider DataProvider)
    {
        _provider = DataProvider;
    }
}

То же с поставщиком

public class EmployeeController : IEmployeeController
{
    private readonly IEmployeeDataProvider _provider;

    [InjectionConstructor]
    public EmployeeController(IEmployeeDataProvider DataProvider)
    {
        _provider = DataProvider;
    }
}

Наконец менеджер сеансов, который содержит только постоянного конструктора.

public class NHibernateSessionManager : INHibernateSessionManager
{   
    private readonly ISessionFactory _sessionFactory;

    public NHibernateSessionManager()
    {            
        _sessionFactory = GetSessionFactory();
    }
}

Таким образом, что происходит, когда запрос страницы запускается BuildUp (), метод называет на странице HttpModule. Единица затем видит Свойство, отмеченное с атрибутом Зависимости, и проверит, что это - контейнер, чтобы видеть, существует ли в нем объект EmployeePresenter.

С тех пор нет такого объекта в контейнере, он затем попытается создать EmployeePresenter. После контроля для создания класса это видит в Предъявителе, он требует конструктора, которому нужен IEmployeeController, введенный в него. Так как контейнер на самом деле имеет менеджера для контроллера, который он будет видеть, существует ли экземпляр его в контейнере, который в начале запроса страницы не существует, таким образом, он пойдет для инстанцирования контроллера.

Unity будет затем видеть, что контроллер требует IEmployeeDataProvider, введенного в него, и он продолжит этот процесс, пока он наконец не перейдет к сути дела, где Поставщику нужен введенный менеджер сеансов. Так как менеджер сеансов больше не имеет потребности в инжекции, Unity затем создаст экземпляр менеджера сеансов, хранят его в контейнере, поскольку это дало ContainerLifeTimeManager, вводит его в Поставщика и хранит тот экземпляр, и так далее вниз туда, где это закончило создавать зависимость EmployeePresenter для страницы.

1
ответ дан 1 December 2019 в 08:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: