c# - Using Unity's dependency injection in (data) annotations -


i using unity , have model tagged data annotations:

public class somemodel {        [slackdisplayname("ed0cad76-263e-496f-abb1-a4dfe6dec5c2")]    public string someproperty { get; set; }     } 

this slackdisplayname property child class of displayname, resolves static display name property. wanted make dynamically having criteria fulfilled:

  1. the use of annotation possible.
  2. i can implement multilingual applications using annotation.
  3. language templates identified guid
  4. i must not pass culture id annotation

so furthermore, slackdisplayname annotation looks this:

/// <summary> /// annotation non-fixed display names /// </summary> public class slackdisplaynameattribute : displaynameattribute {     /// <summary>     /// todo     /// </summary>     /// <param name="identifierguid"></param>     public slackdisplaynameattribute(string identifierguid)         : this(guid.parse(identifierguid))     {     }      /// <summary>     /// todo     /// </summary>     /// <param name="identifier"></param>     public slackdisplaynameattribute(guid identifier)         : base()     {       }      /// <summary>     /// culture context use.     /// </summary>     [dependency]     public iculturecontext context { get; set; }      /// <summary>     /// gets display name given guid.     /// </summary>     public override string displayname     {                 {             return "not_defined";             //return context.getlanguagetemplate(new guid());          }     } } 

and question is: how iculturecontext unity container:

[dependency] public iculturecontext context { get; set; } 

it registered, have no clue how property injected.

i have solved myself!

first of all, need following unity extension , strategy:

info: found here: unitycontainer.buildup() - can make inject new instances properties if these null?

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 = 0; < 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 t ) return true;         }         return false;     }  } 

you need this, because responsible injecting properties on "buildup". next this, need register extension

container.addnewextension<recursivebuildupcontainerextension>(); 

furthermore, need override default dataannotationsmodelmetadataprovider, because default modelmetadataprovider not use unity inject properties annotations. this, implement class:

public class dynamicmodelmetadataprovider : dataannotationsmodelmetadataprovider {     private iunitycontainer _context;      protected override modelmetadata createmetadata(ienumerable<attribute> attributes, type containertype, func<object> modelaccessor, type modeltype, string propertyname)     {                    foreach (attribute attribute in attributes)             _context.buildup(attribute);          return base.createmetadata(attributes, containertype, modelaccessor, modeltype, propertyname);     }      public dynamicmodelmetadataprovider(iunitycontainer context)         : base()     {         this._context = context;     } } 

after that, edit bootstrapper , set new modelmetadataprovider, make clear mvc framework has use it:

modelmetadataproviders.current = new dynamicmodelmetadataprovider(container); 

where container set iunitycontainer. should have instances in annotations instance when having set [dependencyattribute] , methods marked [injectionmethod] should called.

[dependency] public iculturecontext context { get; set; } 

hope use if had similar problem ;)


Comments

Popular posts from this blog

php - Calling a template part from a post -

Firefox SVG shape not printing when it has stroke -

How to mention the localhost in android -