Может ли StructureMap вернуть особый случай?
Я хочу, чтобы StructureMap возвращал особый случай с именем "Нет" для определенного экземпляра.
Скажи, что у меня есть этот класс MyUser
который ограничен как HttpContext. Я хочу иметь вложенный класс dreived None
(То есть. MyUser.None
) который возвращен для типа MyUser
когда нет HttpContext
(например, как в начальной загрузке, Application_Start()
так далее).
Это будет означать, что определенные вызовы могут проверять тип Special Case вместо null (более читаемый), например
if(value is MyUser.None)
// do special case things
else
// do normal case things
Какая конфигурация SM мне нужна для этого? Я попробовал ConditionallyUse
метод без особого успеха. Я продолжаю получать NullReferenceExceptionS
метание изнутри самого СМ.
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>();
});
Я должен был быть более осторожным NullReferenceExceptionS
изнутри SM - моя основная причина, кажется, была проблема с ограничением объема... в частности, как я хотел получить доступ к HttpContext
экземпляр в тесте. Я сейчас использую HybridHttpOrThreadLocalScoped()
Конфиг и быть более осторожным с помощью TryGetInstance()
где уместно вместо GetInstance()
,
Этот код должен работать (чтобы проверить, вы можете заменить проверку 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()
перегрузка, которая занимает Func<>
и сделать условную проверку себя с if
заявление.