3

我有一个上下文对象,我希望能够从大量不同的类中访问它。我的代码看起来像

Context ctx = new Context();
Section section = new Section(ctx) {
    Data1 = new SomeData(ctx) { Value = 123 },
    Data2 = new SomeOtherData(ctx) { Foo = "bar" },
    SubSection = new Section(ctx) {
        MoreData = new MoreData(ctx) { Text = "Hello!" }
    }
};

但我真正想要的是看起来像这样的代码:

using(Context.New()) {
    Section section = new Section() {
        Data1 = new SomeData { Value = 123 },
        Data2 = new SomeOtherData { Foo = "bar" },
        SubSection = new Section {
            MoreData = new MoreData { Text = "Hello!" }
        }
    };
    // do something with section
}

这可能吗?我将在 ASP.NET 和 .exes 中使用它(将来可能还有其他东西),所以我不能只在static某处存储一个或线程本地引用。

它不需要完全像上面那样,只是一种我不必将上下文传递给我创建的每个对象的方式。我考虑过使用扩展方法,context.createSomeData()但它需要每个类更多的样板文件,并且实际上并没有更好,因为您仍然需要上下文对象。

理想情况下应该在 VS2008/.NET3.5 下工作,尽管如果有任何方法可以做到这一点,我仍然会感兴趣。

更新:我最终通过将我的方法重构为以下解决了这个问题:

Section section = new Section {
    Data1 = new SomeData { Value = 123 },
    Data2 = new SomeOtherData { Foo = "bar" },
    SubSection = new Section {
        MoreData = new MoreData { Text = "Hello!" }
    }
};
section.DoStuffWithContext(new Context());

虽然它可能不适用于所有人,但它可以满足我的需要。

如果有人对最初的问题提出一个好的解决方案,我会留下这个问题。

4

3 回答 3

2

您可以定义一个静态方法Context.RetreiveData(),但您不必在方法本身内部实现任何样板代码。

RetreiveData()使用命令模式,每个特定的项目类型都可以为该方法提供自己的实现。ASP.NET 项目可以提供一种从 Session 中检索数据的方法。WinForm 可执行文件可以提供一种从某个全局变量中检索数据的方法。还有一个项目可以提供一种从数据库中检索数据的方法。

于 2013-09-04T13:10:05.007 回答
1

不,没有任何明确的可能性。您甚至在使用对象初始化程序 ( new Obj { ... }),因此您需要使用new运算符(这使得使用 ctx 的静态方法/扩展方法成为不可能)。

你唯一能做的:

SomeData MakeSomeData(this Context ctx, int value)
{
    return new SomeData(ctx) { Value = value };
}

并在初始化中:

Context ctx = new Context();

Section section = new Section(ctx) {
    Data1 = ctx.MakeSomeData(123), ...

但我认为你不会有任何收获

于 2013-09-04T12:41:23.093 回答
0

我第二次hvd对您的问题的评论,我认为这不需要太多样板文件。假设每个类都实现了这个:

public interface IContextConsumer {
    Context Context { get; set; }
}

你的基类有一个这样的方法:

protected void AddChild(IContextConsumer child) {
    child.Context = this.Context;
}

属性实现只需要:

private SomeData _data1;
public SomeData Data1 {
    get { return _data1; }
    set {
        _data1 = value;
        AddChild(_data1);
    }
}

如果您执行以下操作,您甚至可以允许在根上重新分配上下文:

protected void AddChild(IContextConsumer child) {
    Children.Add(child);
    child.Context = this.Context;
}

protected void OnContextChanged() {
    foreach (var child in Children) child.Context = this.Context;
}

派生类只需要调用OnContextChanged它们的Context属性实现。

于 2013-09-06T12:09:19.603 回答