2

我想让 StructureMap为某个实例返回一个名为“None”的特殊情况

假设我有这个MyUser范围为 HttpContext 的类。我想要一个嵌套的、驱动的类None(即。 ),当没有时MyUser.None返回该类型(例如,在引导等中)。MyUserHttpContextApplication_Start()

这意味着某些调用可以检查特殊情况类型而不是 null (更具可读性),例如

if(value is MyUser.None)
  // do special case things
else
  // do normal case things

我需要什么 SM 配置来实现这一点?我已经尝试过这种ConditionallyUse方法,但没有取得多大成功。我不断地NullReferenceExceptionS从 SM 内部扔东西。

4

2 回答 2

2

此代码应该可以工作(为了测试,您可以将 HttpContext.Current 的检查替换DateTime.Now.Millisecond % 2 == 0为更容易看到不同行为的内容):

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()带 a 的重载并使用语句Func<>自己进行条件检查。if

于 2011-08-11T14:11:11.600 回答
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>();
            });

我必须NullReferenceExceptionS从 SM 内部更加小心 - 我的根本原因似乎是范围问题..特别是我希望如何HttpContext在测试中访问范围内的实例。我现在正在使用HybridHttpOrThreadLocalScoped()配置,并且通过使用TryGetInstance()where apppropiate 而不是GetInstance().

于 2011-08-16T07:05:16.380 回答