【问题标题】:Can StructureMap return a Special Case?StructureMap 可以返回一个特例吗?
【发布时间】:2011-08-11 07:00:58
【问题描述】:

我想让 StructureMap 为某个实例返回一个名为“None”的Special Case

假设我有这个类MyUser,它的作用域为 HttpContext。我想要一个嵌套的、派生类None(即MyUser.None),当没有HttpContext时,它会返回MyUser类型(例如,像在引导中,Application_Start()等)。

这意味着某些调用可以检查特殊情况类型,而不是像

这样的 null(更具可读性)
if(value is MyUser.None)
  // do special case things
else
  // do normal case things

我需要什么 SM 配置来实现这一点?我尝试了ConditionallyUse 方法,但没有取得多大成功。我不断收到NullReferenceExceptionS 来自 SM 本身的投掷。

【问题讨论】:

    标签: c# asp.net-mvc structuremap null-object-pattern


    【解决方案1】:

    这段代码应该可以工作(为了测试,您可以将 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 有点奇怪,您可能只想使用采用Func&lt;&gt;Use() 重载并使用if 语句自己进行条件检查。

    【讨论】:

    • 我会尝试一下这些想法。谢谢
    【解决方案2】:

    原来我有潜在的 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() 时更加小心。

    【讨论】:

    • 看来您使用了我的答案,将其写成您的答案,并接受了它。难道你不应该接受我的,只是添加一个你错过了一些 NullReferenceExceptions 之类的评论吗?
    • 不要不尊重乔希。我不是故意让它看起来那样。事实是我已经在使用ConditionallyUse,就像您建议的答案一样(即使我的问题只提到那个我使用它,而不是如何使用它)。这实际上是对我如何通过潜在问题(在代码片段之后)解决的解释,我认为这可能对其他人更有价值。这就是我写一个新答案的原因。实际上,我确实坐下来思考了一段时间,以供参考。非常感谢您的帮助。
    • 没拍,只是想了解一下。很高兴你解决了你的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 2011-08-16
    相关资源
    最近更新 更多