Beispiel #1
0
        /// <summary>
        /// Creates a new <see cref="DualAssemblyResolver"/>.
        /// </summary>
        /// <param name="weavingContext">Weaving context to use in assembly resolution.</param>
        public DualAssemblyResolver(IWeavingContext weavingContext)
        {
            Contract.Requires(weavingContext != null);
            Contract.Ensures(this.WeavingContext != null);

            this.WeavingContext = weavingContext;
        }
Beispiel #2
0
        /// <summary>
        /// Gets the resolved <see cref="TypeDefinition"/> for a given assembly qualified type name.
        /// </summary>
        /// <param name="weavingContext">Context to use when resolving type information.</param>
        /// <param name="assemblyQualifiedTypeName">Assembly qualified name of the type to resolve.</param>
        /// <returns>Resolved type.</returns>
        public static TypeDefinition GetTypeDefinition(this IWeavingContext weavingContext, string assemblyQualifiedTypeName)
        {
            Contract.Requires(weavingContext != null);
            Contract.Requires(assemblyQualifiedTypeName != null);
            Contract.Ensures(Contract.Result <TypeDefinition>() != null);

            var nameParts = assemblyQualifiedTypeName.Split(new[] { ',' }, 2, StringSplitOptions.None);

            if (nameParts.Length != 2)
            {
                throw new ArgumentException("Expected type name and assembly name separated by a comma: " + assemblyQualifiedTypeName, "assemblyQualifiedTypeName");
            }

            var assemblyDefinition = weavingContext.AssemblyResolver.Resolve(AssemblyNameReference.Parse(nameParts[1]));

            if (assemblyDefinition == null)
            {
                throw new ArgumentException("Cannot resolve assembly for type: " + assemblyQualifiedTypeName, "assemblyQualifiedTypeName");
            }

            var typeDefinition = assemblyDefinition.MainModule.GetType(nameParts[0]);

            if (typeDefinition == null)
            {
                throw new ArgumentException("Cannot find type within resolved assembly: " + assemblyQualifiedTypeName, "assemblyQualifiedTypeName");
            }

            return(typeDefinition);
        }
        /// <summary>
        /// Creates a new <see cref="DualAssemblyResolver"/>.
        /// </summary>
        /// <param name="weavingContext">Weaving context to use in assembly resolution.</param>
        public DualAssemblyResolver(IWeavingContext weavingContext)
        {
            Contract.Requires(weavingContext != null);
            Contract.Ensures(this.WeavingContext != null);

            this.WeavingContext = weavingContext;
        }
Beispiel #4
0
        /// <summary>
        /// Projects a DTO type as a nested type inside of the target type.
        /// </summary>
        /// <param name="weavingContext">Weaving context within which the weave is running.</param>
        /// <param name="target">Target type.</param>
        /// <param name="weaveAttribute">Attribute that decorated the target type.</param>
        public void Weave(IWeavingContext weavingContext, TypeDefinition target, CustomAttribute weaveAttribute)
        {
            TypeDefinition dtoType = new TypeDefinition(
                target.Namespace, "Dto",
                TypeAttributes.Class | TypeAttributes.NestedPublic,
                target.Module.Import(typeof(object)));

            target.NestedTypes.Add(dtoType);

            var dtoMemberAttributeType = target.Module.Import(typeof(DtoMemberAttribute)).Resolve();

            foreach (var property in target.Properties)
            {
                for (var i = property.CustomAttributes.Count - 1; i >= 0; --i)
                {
                    var attribute = property.CustomAttributes[i];
                    if (attribute.AttributeType.Resolve() == dtoMemberAttributeType)
                    {
                        property.CustomAttributes.RemoveAt(i);

                        var field = new FieldDefinition(property.Name, FieldAttributes.Public, property.PropertyType);
                        dtoType.Fields.Add(field);
                    }
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Contracts for <see cref="IWeave.Initialize"/>
        /// </summary>
        /// <param name="weavingContext">Context data for command initialization.</param>
        /// <param name="weaveConfig">Configuration data for the command. Commands may require particular types for this argument that are subtypes of <see cref="WeaveConfigTypeBase"/></param>
        public void Initialize(IWeavingContext weavingContext, WeaveConfigTypeBase weaveConfig)
        {
            Contract.Requires(weavingContext != null);
            Contract.Requires(!this.IsInitialized);
            Contract.Ensures(this.IsInitialized);

            throw new NotSupportedException();
        }
Beispiel #6
0
        /// <summary>
        /// Contracts for <see cref="IWeave.Initialize"/>
        /// </summary>
        /// <param name="weavingContext">Context data for command initialization.</param>
        /// <param name="weaveConfig">Configuration data for the command. Commands may require particular types for this argument that are subtypes of <see cref="WeaveConfigTypeBase"/></param>
        public void Initialize(IWeavingContext weavingContext, WeaveConfigTypeBase weaveConfig)
        {
            Contract.Requires(weavingContext != null);
            Contract.Requires(!this.IsInitialized);
            Contract.Ensures(this.IsInitialized);

            throw new NotSupportedException();
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="MethodWeaver"/> class.
 /// </summary>
 /// <param name="classCustomAttributes">Custom attributes of the class of the method.</param>
 /// <param name="context">Method weaving context.</param>
 /// <param name="switchHandlerBuilder">Builder of switch handler, used for populating switch initialization of the class.</param>
 public MethodWeaver(
     IReadOnlyList <CrossCutterN.Aspect.Metadata.ICustomAttribute> classCustomAttributes,
     IWeavingContext context,
     ISwitchHandlerBuilder switchHandlerBuilder)
 {
     this.classCustomAttributes = classCustomAttributes ?? throw new ArgumentNullException("classCustomAttributes");
     this.context = context ?? throw new ArgumentNullException("context");
     this.switchHandlerBuilder = switchHandlerBuilder ?? throw new ArgumentNullException("switchHandlerBuilder");
 }
Beispiel #8
0
        /// <summary>
        /// Contracts for <see cref="IWeave.Weave"/>
        /// </summary>
        /// <param name="weavingContext">Context data for weaving.</param>
        /// <param name="target">The type to which the weave will be applied/</param>
        /// <param name="weaveAttribute">Attribute that may contain arguments for the weave invocation.</param>
        public void Weave(IWeavingContext weavingContext, TypeDefinition target, CustomAttribute weaveAttribute)
        {
            Contract.Requires(weavingContext != null);
            Contract.Requires(target != null);
            Contract.Requires(weaveAttribute != null);
            Contract.Requires(this.IsInitialized);

            throw new NotSupportedException();
        }
Beispiel #9
0
        /// <summary>
        /// Contracts for <see cref="IWeave.Weave"/>
        /// </summary>
        /// <param name="weavingContext">Context data for weaving.</param>
        /// <param name="target">The type to which the weave will be applied/</param>
        /// <param name="weaveAttribute">Attribute that may contain arguments for the weave invocation.</param>
        public void Weave(IWeavingContext weavingContext, TypeDefinition target, CustomAttribute weaveAttribute)
        {
            Contract.Requires(weavingContext != null);
            Contract.Requires(target != null);
            Contract.Requires(weaveAttribute != null);
            Contract.Requires(this.IsInitialized);

            throw new NotSupportedException();
        }
Beispiel #10
0
        /// <summary>
        /// Add switch registering to a class.
        /// </summary>
        /// <param name="clazz">The class to register switch.</param>
        /// <param name="context">The weaving context.</param>
        /// <param name="switchData">Data of switches.</param>
        /// <param name="statistics">Weaving statistics.</param>
        public static void Weave(TypeDefinition clazz, IWeavingContext context, IReadOnlyList <SwitchInitializingData> switchData, IClassWeavingStatisticsBuilder statistics)
        {
#if DEBUG
            if (clazz == null)
            {
                throw new ArgumentNullException("clazz");
            }

            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (switchData == null || !switchData.Any())
            {
                throw new ArgumentNullException("switchData");
            }

            if (statistics == null)
            {
                throw new ArgumentNullException("statistics");
            }
#endif
            var staticConstructor      = clazz.Methods.FirstOrDefault(mthd => mthd.IsStaticConstructor());
            MethodDefinition method    = null;
            ILProcessor      processor = null;
            if (staticConstructor == null)
            {
                method = new MethodDefinition(
                    ".cctor",
                    MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                    context.GetTypeReference(typeof(void)));
                processor = method.Body.GetILProcessor();
                method.Body.Instructions.Add(processor.Create(OpCodes.Ret));
                clazz.Methods.Add(method);
            }
            else
            {
                method    = staticConstructor;
                processor = method.Body.GetILProcessor();
            }

            var typeName     = clazz.GetFullName();
            var instructions = new List <Instruction>();
            foreach (var data in switchData)
            {
                RegisterSwitch(instructions, processor, context, data, typeName);
                statistics.AddSwitchWeavingRecord(StatisticsFactory.InitializeSwitchWeavingRecord(typeName, data.Property, data.MethodSignature, data.Aspect, data.Field.Name, data.Value));
            }

            CompleteSwitchRegistration(method, instructions, processor, context, typeName);
        }
Beispiel #11
0
        private static void WeaveSwitches(
            ISwitchHandler switchHandler,
            TypeDefinition clazz,
            IWeavingContext context,
            IClassWeavingStatisticsBuilder statistics)
        {
            var switchData = switchHandler.GetData().ToList();

            if (switchData.Any())
            {
                SwitchInitializationWeaver.Weave(clazz, context, switchData, statistics);
            }
        }
Beispiel #12
0
        private static void AddAssemblyReference(IWeavingContext context, ModuleDefinition module, IModuleWeavingStatisticsBuilder statistics)
        {
            var assemblyReferences = context.AssemblyReferences;

            if (assemblyReferences != null && assemblyReferences.Any())
            {
                foreach (var reference in assemblyReferences)
                {
                    if (!module.AssemblyReferences.Any(r => Equals(r.Name, reference.Name)))
                    {
                        module.AssemblyReferences.Add(reference);
                        statistics.AddAssemblyReference(reference.FullName);
                    }
                }
            }
        }
        /// <summary>
        /// Creates a new <see cref="WeavingContextAssemblyResolver"/>
        /// </summary>
        /// <param name="weavingContext">Weaving context to pull path data from</param>
        public WeavingContextAssemblyResolver(IWeavingContext weavingContext)
        {
            Contract.Requires(weavingContext != null);

            Contract.Assert(weavingContext.DefineConstants != null);
            Contract.Assert(Directory.Exists(weavingContext.ProjectDirectoryPath));
            Contract.Assert(Directory.Exists(weavingContext.SolutionDirectoryPath));

            // configuration specific path
            var projectRelativePath = Path.Combine("bin", weavingContext.DefineConstants.Contains("DEBUG") ? "Debug" : "Release");
            this.AddSearchDirectory(Path.Combine(weavingContext.ProjectDirectoryPath, projectRelativePath));

            // simple bin path, e.g. for asp.net
            this.AddSearchDirectory(Path.Combine(weavingContext.ProjectDirectoryPath, "bin"));

            // solution tools path for files created not normally available to the weave target assembly
            this.AddSearchDirectory(Path.Combine(weavingContext.SolutionDirectoryPath, "Tools"));
        }
Beispiel #14
0
        /// <summary>
        /// Creates a new <see cref="WeavingContextAssemblyResolver"/>
        /// </summary>
        /// <param name="weavingContext">Weaving context to pull path data from</param>
        public WeavingContextAssemblyResolver(IWeavingContext weavingContext)
        {
            Contract.Requires(weavingContext != null);

            Contract.Assert(weavingContext.DefineConstants != null);
            Contract.Assert(Directory.Exists(weavingContext.ProjectDirectoryPath));
            Contract.Assert(Directory.Exists(weavingContext.SolutionDirectoryPath));

            // configuration specific path
            var projectRelativePath = Path.Combine("bin", weavingContext.DefineConstants.Contains("DEBUG") ? "Debug" : "Release");

            this.AddSearchDirectory(Path.Combine(weavingContext.ProjectDirectoryPath, projectRelativePath));

            // simple bin path, e.g. for asp.net
            this.AddSearchDirectory(Path.Combine(weavingContext.ProjectDirectoryPath, "bin"));

            // solution tools path for files created not normally available to the weave target assembly
            this.AddSearchDirectory(Path.Combine(weavingContext.SolutionDirectoryPath, "Tools"));
        }
Beispiel #15
0
        /// <summary>
        /// Applies the weave to a target type.
        /// </summary>
        /// <param name="weavingContext">Context data for weaving.</param>
        /// <param name="target">The type to which the weave will be applied/</param>
        /// <param name="weaveAttribute">Attribute that may contain arguments for the weave invocation. This must be of type <see cref="InterfaceMixinAttribute"/>.</param>
        /// <exception cref="ArgumentException">
        /// The <paramref name="weaveAttribute"/> is not of type <see cref="InterfaceMixinAttribute"/>, or it does not
        /// contain the expected argument values.
        /// </exception>
        public void Weave(IWeavingContext weavingContext, TypeDefinition target, CustomAttribute weaveAttribute)
        {
            if (weaveAttribute.AttributeType.FullName != weavingContext.GetTypeDefinition(typeof(InterfaceMixinAttribute)).FullName)
            {
                throw new ArgumentException("Must be a valid CustomAttribute with AttributeType InterfaceMixAttribute",
                                            "weaveAttribute");
            }

            if (weaveAttribute.ConstructorArguments.Count != 1)
            {
                throw new ArgumentException("Expected a single constructor argument", "weaveAttribute");
            }

            var mixinInterfaceTypeReference = weaveAttribute.ConstructorArguments[0].Value as TypeReference;

            if (mixinInterfaceTypeReference == null)
            {
                throw new ArgumentException("Expected constructor argument to be a TypeReference", "weaveAttribute");
            }

            var mixinInterfaceType = mixinInterfaceTypeReference.Resolve();

            if (!mixinInterfaceType.IsInterface)
            {
                weavingContext.LogError(string.Format("Configured mixin interface type is not an interface: [{0}]", mixinInterfaceType.FullName));
                // let execution continue...an error will be thrown for this particular weave if invocation is attempted
            }

            var matchedMap = this.Config.InterfaceMixinMap.SingleOrDefault(
                map => map.GetInterfaceType(weavingContext).FullName == mixinInterfaceType.FullName);

            if (matchedMap == null)
            {
                weavingContext.LogWarning("Could not find the a configuration for the requested interface: " + mixinInterfaceType.FullName);
                return;
            }

            new InterfaceMixinWeaver(mixinInterfaceType, matchedMap.GetMixinType(weavingContext), target).Execute();
        }
Beispiel #16
0
        /// <summary>
        /// Gets the resolved <see cref="TypeDefinition"/> for a given <see cref="Type"/>.
        /// </summary>
        /// <param name="weavingContext">Context to use when resolving type information.</param>
        /// <param name="type">Type to resolve.</param>
        /// <returns>Resolved type.</returns>
        public static TypeDefinition GetTypeDefinition(this IWeavingContext weavingContext, Type type)
        {
            Contract.Requires(weavingContext != null);
            Contract.Requires(type != null);
            Contract.Ensures(Contract.Result <TypeDefinition>() != null);

            var assemblyDefinition = weavingContext.AssemblyResolver.Resolve(AssemblyNameReference.Parse(type.Assembly.FullName));

            if (assemblyDefinition == null)
            {
                throw new ArgumentException("Cannot resolve assembly for type: " + type.AssemblyQualifiedName, "type");
            }

            var typeDefinition = assemblyDefinition.MainModule.GetType(type.FullName);

            if (typeDefinition == null)
            {
                throw new ArgumentException("Cannot find type within resolved assembly: " + type.AssemblyQualifiedName, "type");
            }

            return(typeDefinition);
        }
Beispiel #17
0
 /// <summary>
 /// Initializes the command using context and configuration information.
 /// </summary>
 /// <param name="weavingContext">Context information for configuration.</param>
 /// <param name="weaveConfig">Command configuration information. For this command type, the value must be of type <see cref="WeaveConfigTypeBase"/>.</param>
 /// <exception cref="ArgumentException">The <paramref name="weaveConfig"/> is not of type <see cref="WeaveConfigTypeBase"/></exception>
 public void Initialize(IWeavingContext weavingContext, WeaveConfigTypeBase weaveConfig)
 {
     this.Config        = weaveConfig as InterfaceMixinConfigType;
     this.IsInitialized = true;
 }
        /// <summary>
        /// Applies the weave to a target type.
        /// </summary>
        /// <param name="weavingContext">Context data for weaving.</param>
        /// <param name="target">The type to which the weave will be applied/</param>
        /// <param name="weaveAttribute">Attribute that may contain arguments for the weave invocation. This must be of type <see cref="InterfaceMixinAttribute"/>.</param>
        /// <exception cref="ArgumentException">
        /// The <paramref name="weaveAttribute"/> is not of type <see cref="InterfaceMixinAttribute"/>, or it does not
        /// contain the expected argument values.
        /// </exception>
        public void Weave(IWeavingContext weavingContext, TypeDefinition target, CustomAttribute weaveAttribute)
        {
            if (weaveAttribute.AttributeType.FullName != weavingContext.GetTypeDefinition(typeof(InterfaceMixinAttribute)).FullName)
            {
                throw new ArgumentException("Must be a valid CustomAttribute with AttributeType InterfaceMixAttribute",
                    "weaveAttribute");
            }

            if (weaveAttribute.ConstructorArguments.Count != 1)
            {
                throw new ArgumentException("Expected a single constructor argument", "weaveAttribute");
            }

            var mixinInterfaceTypeReference = weaveAttribute.ConstructorArguments[0].Value as TypeReference;

            if (mixinInterfaceTypeReference == null)
            {
                throw new ArgumentException("Expected constructor argument to be a TypeReference", "weaveAttribute");
            }

            var mixinInterfaceType = mixinInterfaceTypeReference.Resolve();

            if (!mixinInterfaceType.IsInterface)
            {
                weavingContext.LogError(string.Format("Configured mixin interface type is not an interface: [{0}]", mixinInterfaceType.FullName));
                // let execution continue...an error will be thrown for this particular weave if invocation is attempted
            }

            var matchedMap = this.Config.InterfaceMixinMap.SingleOrDefault(
                map => map.GetInterfaceType(weavingContext).FullName == mixinInterfaceType.FullName);

            if(matchedMap == null)
            {
                weavingContext.LogWarning("Could not find the a configuration for the requested interface: " + mixinInterfaceType.FullName);
                return;
            }

            new InterfaceMixinWeaver(mixinInterfaceType, matchedMap.GetMixinType(weavingContext), target).Execute();
        }
 /// <summary>
 /// Initializes the command using context and configuration information.
 /// </summary>
 /// <param name="weavingContext">Context information for configuration.</param>
 /// <param name="weaveConfig">Command configuration information. For this command type, the value must be of type <see cref="WeaveConfigTypeBase"/>.</param>
 /// <exception cref="ArgumentException">The <paramref name="weaveConfig"/> is not of type <see cref="WeaveConfigTypeBase"/></exception>
 public void Initialize(IWeavingContext weavingContext, WeaveConfigTypeBase weaveConfig)
 {
     this.Config = weaveConfig as InterfaceMixinConfigType;
     this.IsInitialized = true;
 }
Beispiel #20
0
 private static void RegisterSwitch(List <Instruction> instructions, ILProcessor processor, IWeavingContext context, SwitchInitializingData data, string typeName)
 {
     instructions.Add(processor.Create(OpCodes.Call, context.BaseReference.BackStage.BuilderGetterReference));
     instructions.Add(processor.Create(OpCodes.Ldstr, typeName));
     instructions.Add(processor.Create(OpCodes.Ldstr, data.Property ?? string.Empty));
     instructions.Add(processor.Create(OpCodes.Ldstr, data.MethodSignature));
     instructions.Add(processor.Create(OpCodes.Ldstr, data.Aspect));
     instructions.Add(processor.Create(data.Value ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0));
     instructions.Add(processor.Create(OpCodes.Callvirt, context.BaseReference.Builder.RegisterSwitchMethod));
     instructions.Add(processor.Create(OpCodes.Stsfld, data.Field));
 }
Beispiel #21
0
        /// <summary>
        /// Projects a DTO type as a nested type inside of the target type.
        /// </summary>
        /// <param name="weavingContext">Weaving context within which the weave is running.</param>
        /// <param name="target">Target type.</param>
        /// <param name="weaveAttribute">Attribute that decorated the target type.</param>
        public void Weave(IWeavingContext weavingContext, TypeDefinition target, CustomAttribute weaveAttribute)
        {
            TypeDefinition dtoType = new TypeDefinition(
                target.Namespace, "Dto",
                TypeAttributes.Class | TypeAttributes.NestedPublic,
                target.Module.Import(typeof(object)));
            target.NestedTypes.Add(dtoType);

            var dtoMemberAttributeType = target.Module.Import(typeof (DtoMemberAttribute)).Resolve();

            foreach (var property in target.Properties)
            {
                for (var i = property.CustomAttributes.Count - 1; i >= 0; --i)
                {
                    var attribute = property.CustomAttributes[i];
                    if (attribute.AttributeType.Resolve() == dtoMemberAttributeType)
                    {
                        property.CustomAttributes.RemoveAt(i);

                        var field = new FieldDefinition(property.Name, FieldAttributes.Public, property.PropertyType);
                        dtoType.Fields.Add(field);
                    }
                }
            }
        }
Beispiel #22
0
 /// <summary>
 /// Gets the mixin implementation type.
 /// </summary>
 /// <param name="weavingContext">Context to use for resolving the type.</param>
 /// <returns>Resolved mixin definition type.</returns>
 public TypeDefinition GetMixinType(IWeavingContext weavingContext)
 {
     Contract.Requires(weavingContext != null);
     return(weavingContext.GetTypeDefinition(this.Mixin));
 }
 /// <summary>
 /// Gets the mixin implementation type.
 /// </summary>
 /// <param name="weavingContext">Context to use for resolving the type.</param>
 /// <returns>Resolved mixin definition type.</returns>
 public TypeDefinition GetMixinType(IWeavingContext weavingContext)
 {
     Contract.Requires(weavingContext != null);
     return weavingContext.GetTypeDefinition(this.Mixin);
 }
Beispiel #24
0
 /// <summary>
 /// Initializes the weave.
 /// </summary>
 /// <param name="weavingContext">Weaving context that is initializing the weave.</param>
 /// <param name="weaveConfig">Must be null for this type of weave.</param>
 public void Initialize(IWeavingContext weavingContext, WeaveConfigTypeBase weaveConfig)
 {
     this.IsInitialized = true;
 }
Beispiel #25
0
 private static void CompleteSwitchRegistration(MethodDefinition method, List <Instruction> instructions, ILProcessor processor, IWeavingContext context, string clazz)
 {
     instructions.Add(processor.Create(OpCodes.Call, context.BaseReference.BackStage.BuilderGetterReference));
     instructions.Add(processor.Create(OpCodes.Ldstr, clazz));
     instructions.Add(processor.Create(OpCodes.Callvirt, context.BaseReference.Builder.CompleteMethod));
     IlUtilities.PersistentInstructions(instructions, processor, method.Body.Instructions.First());
 }
Beispiel #26
0
 /// <summary>
 /// Initializes the weave.
 /// </summary>
 /// <param name="weavingContext">Weaving context that is initializing the weave.</param>
 /// <param name="weaveConfig">Must be null for this type of weave.</param>
 public void Initialize(IWeavingContext weavingContext, WeaveConfigTypeBase weaveConfig)
 {
     this.IsInitialized = true;
 }
Beispiel #27
0
 /// <summary>
 /// Gets the mixin definition interface.
 /// </summary>
 /// <param name="weavingContext">Context to use for resolving the type.</param>
 /// <returns>Resolved mixin definition interface type.</returns>
 public TypeDefinition GetInterfaceType(IWeavingContext weavingContext)
 {
     Contract.Requires(weavingContext != null);
     return(weavingContext.GetTypeDefinition(this.Interface));
 }
 /// <summary>
 /// Gets the mixin definition interface.
 /// </summary>
 /// <param name="weavingContext">Context to use for resolving the type.</param>
 /// <returns>Resolved mixin definition interface type.</returns>
 public TypeDefinition GetInterfaceType(IWeavingContext weavingContext)
 {
     Contract.Requires(weavingContext != null);
     return weavingContext.GetTypeDefinition(this.Interface);
 }