我有一个上下文对象,我希望能够从大量的差异类中访问。我的代码看起来像
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());
虽然它可能对每个人都不起作用,但它确实符合我的需要。
如果有人为最初的问题提出了一个很好的解决方案,我会把这个问题保留下来。
答案 0 :(得分:2)
您可以定义静态方法Context.RetreiveData()
,但不必在方法本身内部实现任何样板代码。
使用命令模式,每个特定项目类型都可以为RetreiveData()
方法提供自己的实现。 ASP.NET项目可以提供一种可以从Session中检索数据的方法。 WinForm可执行文件可以提供一种方法,可以从某个全局变量中检索数据。另一个项目可以提供一种从DB中检索数据的方法。
答案 1 :(得分: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), ...
但我认为你不会得到任何东西
答案 2 :(得分: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
。