Сообщение Re[13]: О пользе Dependency Injection от 15.01.2021 23:01
Изменено 15.01.2021 23:02 Somescout
Re[13]: О пользе Dependency Injection
Здравствуйте, ·, Вы писали:
·>Здравствуйте, Somescout, Вы писали:
S>> Нет, не правильно: код остался полностью без изменений. Только вместо вызова вида:
S>>
·>Лукавство. Ты покажи _весь_ код, откуда ты взял serviceProvider?
В смысле? Взял из конструктора:
Если вам интересен вариант когда провайдер создаётся вручную, то примерно так (псевдокод):
Понятно что этот способ (т.е. через ServiceProvider) используется исключительно в том случае, когда инициализация SomeObject дорогая и сам объект используется он не всегда (я использую его только в контроллере, когда лишь часть экшенов использует его), в обычном случае будет:
S>> Появилось
S>>
·>А вот это _весь_ код. Помещай его в main и запускай, будет работать. Притом быстро, без всяких рефлексий, рантайм-ошибок и километровых стек-трейсов.
Ну да, сравниете с ручным созданием ServiceProvider — разница в несколько строк. И да, у меня почему-то ни разу не возникало ситуации, когда проблемы с DI были с "рантайм-ошибок и километровых стек-трейсов" — обычно просто сообщение, что требуемый объект не зарегистрирован.
S>> Вот и всё различие. Внутренности SomeObject не менялись.
·>Не понял, а зачем их менять?
Это вы у IT спросите. Я с самого начала писал что там ничего не менялось.
·>Здравствуйте, Somescout, Вы писали:
S>> Нет, не правильно: код остался полностью без изменений. Только вместо вызова вида:
S>>
var instance = serviceProvider.Get<SomeObject>()·>Лукавство. Ты покажи _весь_ код, откуда ты взял serviceProvider?
В смысле? Взял из конструктора:
public class CallerObj {
private readonly IServiceProvider serviceProvider;
public CallerObj(IServiceProvider serviceProvider) {
this.serviceProvider = serviceProvider;
}
public void Something() {
var instance = serviceProvider.Get<SomeObject>();
}
}Если вам интересен вариант когда провайдер создаётся вручную, то примерно так (псевдокод):
public void Something() {
var serviceBuilder = new ServiceBuilder();
serviceBuilder
.Bind<IDbContext,DbContext>(Scope.Request) // Просто для примера - понято что области запроса в данном случае нет
.Bind<IAppConfig, AppConfig>(Scope.Singleton);
serviceBuilder.Bind<SomeObject>(Scope.Transient); // Тут зависит от реализации DI: NInject умеет создавать произвольный объект,
// если для него зарегистрированы все зависимости, MS DI (из NetCore)
// требует явной регистрации всех создаваемых объектов
var serviceProvider = serviceBuilder.Build;
var instance = serviceProvider.Get<SomeObject>();
}Понятно что этот способ (т.е. через ServiceProvider) используется исключительно в том случае, когда инициализация SomeObject дорогая и сам объект используется он не всегда (я использую его только в контроллере, когда лишь часть экшенов использует его), в обычном случае будет:
public class CallerObj {
private readonly SomeObject someObject;
public CallerObj(SomeObject someObject) {
this.someObject = someObject;
}
public void Something() {
...
}
}S>> Появилось
S>>
S>> var db = new DbContext();
S>> var config = new AppConfig();
S>> var instance = new SomeObject(db, config);
S>>·>А вот это _весь_ код. Помещай его в main и запускай, будет работать. Притом быстро, без всяких рефлексий, рантайм-ошибок и километровых стек-трейсов.
Ну да, сравниете с ручным созданием ServiceProvider — разница в несколько строк. И да, у меня почему-то ни разу не возникало ситуации, когда проблемы с DI были с "рантайм-ошибок и километровых стек-трейсов" — обычно просто сообщение, что требуемый объект не зарегистрирован.
S>> Вот и всё различие. Внутренности SomeObject не менялись.
·>Не понял, а зачем их менять?
Это вы у IT спросите. Я с самого начала писал что там ничего не менялось.
Re[13]: О пользе Dependency Injection
Здравствуйте, ·, Вы писали:
·>Здравствуйте, Somescout, Вы писали:
S>> Нет, не правильно: код остался полностью без изменений. Только вместо вызова вида:
S>>
·>Лукавство. Ты покажи _весь_ код, откуда ты взял serviceProvider?
В смысле? Взял из конструктора:
Если вам интересен вариант когда провайдер создаётся вручную, то примерно так (псевдокод):
Понятно что этот способ (т.е. через ServiceProvider) используется исключительно в том случае, когда инициализация SomeObject дорогая и сам объект используется он не всегда (я использую его только в контроллере, когда лишь часть экшенов использует его), в обычном случае будет:
S>> Появилось
S>>
·>А вот это _весь_ код. Помещай его в main и запускай, будет работать. Притом быстро, без всяких рефлексий, рантайм-ошибок и километровых стек-трейсов.
Ну да, сравниете с ручным созданием ServiceProvider — разница в несколько строк. И да, у меня почему-то ни разу не возникало ситуации, когда проблемы с DI были с "рантайм-ошибок и километровых стек-трейсов" — обычно просто сообщение, что требуемый объект не зарегистрирован.
S>> Вот и всё различие. Внутренности SomeObject не менялись.
·>Не понял, а зачем их менять?
Это вы у IT спросите. Я с самого начала писал что там ничего не менялось.
·>Здравствуйте, Somescout, Вы писали:
S>> Нет, не правильно: код остался полностью без изменений. Только вместо вызова вида:
S>>
var instance = serviceProvider.Get<SomeObject>()·>Лукавство. Ты покажи _весь_ код, откуда ты взял serviceProvider?
В смысле? Взял из конструктора:
public class CallerObj {
private readonly IServiceProvider serviceProvider;
public CallerObj(IServiceProvider serviceProvider) {
this.serviceProvider = serviceProvider;
}
public void Something() {
var instance = serviceProvider.Get<SomeObject>();
}
}Если вам интересен вариант когда провайдер создаётся вручную, то примерно так (псевдокод):
public void Something() {
var serviceBuilder = new ServiceBuilder();
serviceBuilder
.Bind<IDbContext,DbContext>(Scope.Request) // Просто для примера - понято что области запроса в данном случае нет
.Bind<IAppConfig, AppConfig>(Scope.Singleton);
serviceBuilder.Bind<SomeObject>(Scope.Transient); // Тут зависит от реализации DI: NInject умеет создавать произвольный объект,
// если для него зарегистрированы все зависимости, MS DI (из NetCore)
// требует явной регистрации всех создаваемых объектов
var serviceProvider = serviceBuilder.Build();
var instance = serviceProvider.Get<SomeObject>();
}Понятно что этот способ (т.е. через ServiceProvider) используется исключительно в том случае, когда инициализация SomeObject дорогая и сам объект используется он не всегда (я использую его только в контроллере, когда лишь часть экшенов использует его), в обычном случае будет:
public class CallerObj {
private readonly SomeObject someObject;
public CallerObj(SomeObject someObject) {
this.someObject = someObject;
}
public void Something() {
...
}
}S>> Появилось
S>>
S>> var db = new DbContext();
S>> var config = new AppConfig();
S>> var instance = new SomeObject(db, config);
S>>·>А вот это _весь_ код. Помещай его в main и запускай, будет работать. Притом быстро, без всяких рефлексий, рантайм-ошибок и километровых стек-трейсов.
Ну да, сравниете с ручным созданием ServiceProvider — разница в несколько строк. И да, у меня почему-то ни разу не возникало ситуации, когда проблемы с DI были с "рантайм-ошибок и километровых стек-трейсов" — обычно просто сообщение, что требуемый объект не зарегистрирован.
S>> Вот и всё различие. Внутренности SomeObject не менялись.
·>Не понял, а зачем их менять?
Это вы у IT спросите. Я с самого начала писал что там ничего не менялось.