Рассмотрим этот абстрактный класс
public abstract class Foo
{
public Injectable Prop {get;set;}
}
У меня есть приложение, которое я хочу улучшить и одновременно сделать рефакторинг для простоты.У меня есть более 100 классов, которые вызывают одни и те же вещи (например, Class Injectable
), и я думаю, что это поведение можно абстрагировать и установить в базовый класс, и каждый будет наследовать от этого базового класса, чтобы удалить код копирования / вставки,
Однако я хочу избежать копирования / вставки кода в конфигурационный файл Spring, определив объект Injectable
, а затем определив дочерний объект foreach и каждый класс, который наследуется от Foo
.
Я ищу способ установить свойства абстрактного класса, а затем все дочерние элементы, чтобы автоматически получать их через конфигурацию.Я хочу избежать создания абстрактного класса следующим образом:
public abstract class Foo
{
public Injectable Prop
{
get { return (Injectable)ContextRegistry.GetContext()["Injectable"]; }
}
}
спасибо за любые предложения
РЕДАКТИРОВАТЬ: чтобы сделать вещи немного сложнее, дочерние классы являются страницами ASP.NET, поэтомуя имею ограниченный контроль над тем, как они генерируются.
В настоящее время я использую вышеупомянутый код, где абстрактный класс делает ссылку на созданный объект DI с идентификатором «Injectable».Я хотел бы избежать летающих строк
ОБНОВЛЕНИЕ (с решением)
Рассмотрим: Классы
public abstract class BasePage : System.Web.UI.Page
{
public IInjectable FooProp {get;set;}
}
public abstract class BaseControl : System.Web.UI.UserControl
{
public IInjectable FooProp {get;set;}
}
public partial class ChildPage : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
FooProp.DoSomeThing();
}
}
public partial class ChildControl : BaseControl
{
protected void Page_Load(object sender, EventArgs e)
{
FooProp.DoSomeThing();
}
}
Весна CFG...
<object id="Injectable" type="ConcreteInjectable">
<property name="SomeProp" value="Injected!!" />
</object>
<!--The requirement is to declare something like:-->
<object type="BasePage" abstract="true">
<property name="FooProp" ref="Injectable />
</object>
<!--it works for usercontrols too-->
<object type="BaseControl" abstract="true">
<property name="FooProp" ref="Injectable />
</object>
и для каждого наследника BasePage
эффект будет иметь свойство FooProp
, введенное в то, что я настроил.
это мало что значит, если это может бытьдостигается с помощью некоторого соглашения о связывании, но я не хочу использовать строки и использовать ссылки DI из моего кода.
2-е ОБНОВЛЕНИЕ И РЕШЕНИЕ благодаря tobsen и Эрих Эйхингер решение было найдено: во-первых, это изначально не поддерживается, но решение не очень уродливо и не нарушает нормы паттернов DI
Теперь,вся необходимая конфигурация пружины приведена выше (в обновлении). Решение Эриха таково: IHttpModule
сделайте так:
public class PageModuleInjecter : IHttpModule
{
public void Dispose() {}
public void Init(HttpApplication context) {
context.PreRequestHandlerExecute += context_PreRequestHandlerExecute;
}
void context_PreRequestHandlerExecute(object sender, EventArgs e) {
IHttpHandler handler = ((HttpApplication )sender).Context.Handler;
if (handler is BasePage)
Spring.Context.Support.WebApplicationContext.Current
.ConfigureObject(handler, typeof(BasePage).FullName);
}
}
и все!(не забудьте зарегистрировать модуль в web.config как всегда)
В поисках функциональности (и, возможно, элегантности) я обнаружил, что вместо использования IHttpModule
(я еще не хотел добавлятьдругой класс) вы можете объявить BasePage
как таковой
public abstract class BasePage : System.Web.UI.Page
{
public IInjectable FooProp {get;set;}
protected override OnPreInit(EventArgs e)
{
Spring.Context.Support.WebApplicationContext.Current
.ConfigureObject(this, typeof(BasePage).FullName);
base.OnPreInit(e);
}
}
, и он работает как чудо, не требуя добавления каких-либо дополнительных модулей и т. д.
Радостно, что это работает и в UserControls (хотя идругое событие в жизненном цикле, поскольку OnPreInit не существует для пользовательских элементов управления):
public abstract class BaseControl : System.Web.UI.UserControl
{
public IInjectable FooProp {get;set;}
protected override OnInit(EventArgs e)
{
Spring.Context.Support.WebApplicationContext.Current
.ConfigureObject(this, typeof(BaseControl).FullName);
base.OnInit(e);
}
}
спасибо за просмотр!