c# - UnityContainer.BuildUp() - 仅当属性为空时,我可以让它将新实例注入(inject)到属性中吗?

标签 c# unity-container ioc-container property-injection

我正在反序列化这样的类

class AClass{
    [Dependency]
    AnotherClass Property{ get; set; }
}

当我使用 BuildUp() 对象时,仅当属性为 null 时,我才希望 Unity 创建 AnotherClass 的新实例,否则仅对其执行 BuildUp。 有没有简单的方法可以实现这一点?

编辑:我正在使用 wpf 进行 mvvm。这些类是 View 模型,我将它们序列化,因为我想在运行之间保留一些属性,并且它们还有一些我想要统一注入(inject)的依赖项。因此,在反序列化之后,嵌套模型已经存在并设置了属性,因此我不希望 Unity 用新实例覆盖它,但我仍然希望它在其上调用 InjectionMethods 并在程序第一次运行时正常解析它,嵌套模型为空。

最佳答案

我最终编写了一个统一扩展。 我找不到太多关于如何执行此操作的文档,所以我不太确定结果。 它似乎有效,但我有这种感觉我可能写了一些可怕的东西.. 无论如何,这是代码,欢迎改进:

public class RecursiveBuildUpContainerExtension : UnityContainerExtension {
        protected override void Initialize(){
            Context.Strategies.Add( new RecursiveBuildUpBuilderStrategy( Context.Container ), UnityBuildStage.PreCreation );
        }
    }

    public class RecursiveBuildUpBuilderStrategy : BuilderStrategy {
        readonly IUnityContainer container;
        public RecursiveBuildUpBuilderStrategy( IUnityContainer container ) {
            this.container = container;
        }

        public override void PreBuildUp( IBuilderContext context ) {

            if( context.Existing == null ) return;

            foreach( var prop in context.Existing.GetType( ).GetProperties( ) ) {

                if( ContainsType<DependencyAttribute>( prop.GetCustomAttributes( true ) ) ) {

                    if( prop.GetValue( context.Existing, null ) == null ) {
                        var value = container.Resolve( prop.PropertyType );
                        prop.GetSetMethod( ).Invoke( context.Existing, new[] { value } );
                    }
                    else {
                        var value = container.BuildUp( prop.PropertyType, prop.GetValue( context.Existing, null ) );
                        prop.GetSetMethod( ).Invoke( context.Existing, new[] { value } );
                    }
                }
            }

            foreach (var method in context.Existing.GetType().GetMethods() ){
                if( ContainsType<InjectionMethodAttribute>( method.GetCustomAttributes( true ))){
                    var argsInfo = method.GetParameters( );
                    var args = new object[argsInfo.Length];

                    for( int i = 0; i < argsInfo.Length; i++ ) {
                        args[i] = container.Resolve( argsInfo[i].ParameterType );
                    }

                    method.Invoke( context.Existing, args );
                }
            }

            context.BuildComplete = true;
        }

        private static bool ContainsType<T>( IEnumerable<object> objects ){
            foreach (var o in objects){
                if( o is T ) return true;
            }
            return false;
        }

    }

关于c# - UnityContainer.BuildUp() - 仅当属性为空时,我可以让它将新实例注入(inject)到属性中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7120476/

相关文章:

c# - 如何测试使用 BackgroundWorker 加载的 ViewModel?

c# - UNITY : How to implement thread safe Container. 带有构造函数注入(inject)的 Resolve() 函数?

c# - Web API Controller 的简单注入(inject)器生活方式警告

c# - 如何在 GetInstance 调用/替代解决方案后在简单注入(inject)器中进行注册?

c# - MEF = 可能会遇到挫折?

c# - 使用FileHelperAsyncEngine崩溃无一异常(exception)

c# - 从 ViewModel 更新 UI 线程

c# - Dapper map multiple join Sql Query

c# - 如何解决应用了 Authorize 属性的 MVC Controller 的鸡生蛋依赖关系解析?

wcf - 使 WCF OperationContext 与 DI 和测试很好地配合使用