在运行时从StructureMap中删除默认实例类型

时间:2011-01-10 10:47:13

标签: c# dependency-injection structuremap ioc-container

是否可以在运行时删除映射?我可以轻松添加一个:

ObjectFactory.Configure(ce => 
       ce.ForRequestedType<IDateAdjuster>().
           TheDefaultIsConcreteType<DateAdjusterForTest>());

我可以查看

是否存在映射
ObjectFactory.Model.HasDefaultImplementationFor<IDateAdjuster>()

但我似乎无法删除默认实例类型。我试过这个

var config = ObjectFactory.Model.PluginTypes
           .FirstOrDefault(pt => pt.PluginType == typeof(IDateAdjuster));
if (config != null) {config.Default = null;}

但这不起作用。

界面的作用是隐藏DateTime.NowDateTime.Today属性,以便在测试期间,特别是集成和用户接受度,系统可以配置为在它看到时转移当前日期和时间它

我试图做的是检查是否有接口的默认实现,如果有,那么我创建并调用它,如果没有那么我只使用DateTime.Now和{ {1}}

<小时/> 因为我似乎无法告诉结构图删除默认类型,所以我现在添加了一个新的接口默认实现,并扩展了接口以具有一个属性来指示它是否处于活动状态。默认实现表明接口未处于活动状态。所以现在我总是可以得到一个实例,然后检查我是否要使用它。

系统具有相当多的日期和时间特定行为,因此客户端需要能够测试系统在不同日期和时间的行为方式。他们登录到admin部分,然后将日期和时间设置为适当的值,然后我将默认实现切换到进行适当调整的测试实现。

由于只是接口的实现发生变化,我只是在客户端管理员设置时切换我想要使用的实现,然后在完成后重置它

2 个答案:

答案 0 :(得分:2)

在运行时更改IoC配置有点可怕的IMO。也许使用工厂将是更清洁的解决方案。例如:

public interface IOptionalFactory
{
    IOptional GetInstance(IPrinciple currentUser);
}

您可以注入IOptionalFactory而不是IOptional接口,让工厂根据提供的用户信息返回不同的实例。

答案 1 :(得分:1)

因此,如果交换机由用户更改的内容控制,我猜它在数据库中或者可能是会话?如果是这种情况,您可以使用StructureMap的条件构造功能来执行此操作:

var container = new Container(x =>
{         
  x.InstanceOf<IDateAdjuster>().Is.Conditional(o =>
  {                 
    o.If(c => c.GetInstance<IUserSettings>()
     .UseTestDateAdjuster).ThenIt.Is.OfConcreteType<DateAdjusterForTest>();

    o.TheDefault.Is.OfConcreteType<DateAdjuster>();
  });
});

IUserSettings可以是您的包含中注册的任何内容,它会告诉您用户是否在管理部分中设置了日期和时间。

有关详细信息,请参阅此博客:http://codebetter.com/jeremymiller/2009/01/19/conditional-object-construction-in-structuremap-i-e-fun-with-lambdas/