2017-06-21 60 views
2

我正在尝试使用我的UnityContainer创建一个智能IOC解析器,该解析器将从解析过程的一部分接收来自第三方服务的信息。使用UnityContainer进行动态IOC映射 - 我该如何实现?

如果一个配置项通常是这样的(我已经创建别名对所有类型):

<type type="IMyInterface" mapTo="MyInstance"> 
    <lifetime type="Hierarchical" /> 
</type> 

我想删除mapTo,并在运行时提供它(每个相关解析请求)。

现在,我试着通过创建一个UnityContainerExtension和一个BuilderStrategy来做这件事,事情变得凌乱并且部分工作。

由于我只想覆盖mapTo部分,我想也许我已经走了很远。

那么,我该如何实现这种功能呢?
是否有反正我可以重写mapTo的getter \ strategy?

+0

你要解决'IMyInterface'直接?或者最终依赖于'IMyInterface'的另一种类型?你能提供一个例子吗? –

+0

我将执行api调用,取回提示,这将帮助我选择“mapTo”类型(实现IMyInterface),并且我希望UnityContainer可以使用新的mapTo类型。一种mapTo运行时工厂。 例如:界面是IVehicle。当我需要解析IVehicle时,我需要计算映射类型。我想执行api调用并返回正确的类型(在本例中可能是Truck或SportsCar)。 –

+0

为什么不直接解决具体类型?例如卡车或SportsCar –

回答

2

好吧,我找到了钩子。

首先,你需要创建一个BuilderStrategy将查找新的映射:

public class DynamicMappingBuildStrategy: BuilderStrategy 
{ 
    public override void PreBuildUp(IBuilderContext context) 
    { 
     var policy = context.Policies.Get<IBuildKeyMappingPolicy>(context.BuildKey); 

     if (policy != null) 
     { 
      context.BuildKey = policy.Map(context.BuildKey, context); 
     } 
     else 
     { 
      var oldMapping = context.BuildKey; 
      var mappedType = DynamicMapper.GetMapping(oldMapping.Type); 
      context.BuildKey = new NamedTypeBuildKey(mappedType, null); 
      var lifetime = context.PersistentPolicies.Get<ILifetimePolicy>(oldMapping, true); 

      if (lifetime != null) 
      { 
       context.PersistentPolicies.Set(lifetime, context.BuildKey); 
      } 
     } 
    } 
} 

然后,你需要创建一个UnityContainerExtension将在正确的UnityBuildStage添加BuilderStrategy

public class DynamicMappingBehaviorExtension : UnityContainerExtension 
{ 
    protected override void Initialize() 
    { 
     this.Context.Strategies.AddNew<DynamicMappingBuildStrategy>(UnityBuildStage.TypeMapping); 
    } 
} 

然后您需要配置您的容器以使用新的扩展名:

<containers> 
      <container> 
       <extensions> 
        <add type="MyNamespace.DynamicMappingBehaviorExtension, MyDll" /> 
       </extensions> 
....More configuration..... 

然后你需要添加你的类型映射没有mapTo:

<type type="IVehicle"> 
    <lifetime type="Hierarchical" /> 
</type>