我想让StructureMap为某个实例返回一个名为“None”的Special Case。
说我有这个类MyUser
,它的作用域是HttpContext。我希望有一个嵌套的,可能的类None
(即MyUser.None
),当没有MyUser
时,它会被HttpContext
类型重新调整(例如,像在引导中一样) ,Application_Start()
等。
这意味着某些调用可以检查特殊情况类型而不是null(更易读),如
if(value is MyUser.None)
// do special case things
else
// do normal case things
我需要什么SM配置来实现这一目标?我尝试了ConditionallyUse
方法但没有取得多大成功。我一直在SM内部投掷NullReferenceExceptionS
。
答案 0 :(得分:2)
这段代码应该可以工作(要测试,你可以用DateTime.Now.Millisecond % 2 == 0
替换HttpContext.Current的检查,以便更容易地看到不同的行为):
class Program
{
static void Main(string[] args)
{
ObjectFactory.Initialize(x =>
{
x.For<IUser>().ConditionallyUse(cond =>
{
cond.TheDefault.Is.Type<MyUser>();
cond.If(ctx =>
{
var hasContext = false;
try
{
hasContext = HttpContext.Current == null;
}catch
{
// HttpContext.Current sometimes throws when there isn't one
}
return hasContext;
}).ThenIt.IsThis(new MyUser.None());
});
});
var instance = ObjectFactory.GetInstance<IUser>();
Console.WriteLine(instance.GetType());
}
public interface IUser{}
public class MyUser : IUser { public class None : IUser {} }
}
由于ConditionallyUse()
API有点奇怪,您可能只想使用Use()
的{{1}}重载并使用Func<>
自行进行条件检查言。
答案 1 :(得分:1)
原来我有基本的SM配置问题。
我仍在使用ConditionallyUse
方法:
For<User>().ConditionallyUse(config =>
{
config.If(ctx => ctx.GetInstance<HttpContextBase>().User == null)
.ThenIt.Is.Type<User.None>();
config.TheDefault.Is.Type<User>();
});
我必须对SM中的NullReferenceExceptionS
更加小心 - 我的根本原因似乎是scoping issue ..特别是我想要访问一个HttpContext
范围的实例测试。我现在正在使用HybridHttpOrThreadLocalScoped()
配置,并且使用适当的TryGetInstance()
代替GetInstance()
更加谨慎。