/// <inheritdoc/> public IPropertyWeavingPlan MakePlan(IProperty property) { readOnly.Assert(true); var getterPlan = WeaverFactory.InitializeWeavingPlan(); var setterPlan = WeaverFactory.InitializeWeavingPlan(); foreach (var aspectEntry in aspects) { var aspect = aspectEntry.Value; var propertyConcern = aspect.CanApplyTo(property); if (propertyConcern.IsConcerned()) { foreach (var joinPoint in aspect.PointCut) { var advice = aspect.GetAdvice(joinPoint); var aspectName = aspectEntry.Key; var info = joinPoints[joinPoint][aspectName]; if (propertyConcern.IsGetterConcerned()) { getterPlan.AddJoinPoint(joinPoint, aspectName, advice, info.Sequence, info.ParameterFlag, aspect.IsSwitchedOn); } if (propertyConcern.IsSetterConcerned()) { setterPlan.AddJoinPoint(joinPoint, aspectName, advice, info.Sequence, info.ParameterFlag, aspect.IsSwitchedOn); } } } } return(WeaverFactory.InitializePropertyWeavingPlan(getterPlan.Build(), setterPlan.Build())); }
/// <inheritdoc/> public IWeavingPlan MakePlan(IMethod method) { readOnly.Assert(true); var plan = WeaverFactory.InitializeWeavingPlan(); foreach (var aspectEntry in aspects) { var aspect = aspectEntry.Value; if (aspect.CanApplyTo(method)) { foreach (var joinPoint in aspect.PointCut) { var advice = aspect.GetAdvice(joinPoint); var id = aspectEntry.Key; var info = joinPoints[joinPoint][id]; plan.AddJoinPoint(joinPoint, id, advice, info.Sequence, info.ParameterFlag, aspect.IsSwitchedOn); } } } return(plan.Build()); }
/// <inheritdoc/> public IAssemblyWeavingStatistics Weave(string inputAssemblyPath, bool includeSymbol, string outputAssemblyPath, string strongNameKeyFile) { if (string.IsNullOrWhiteSpace(inputAssemblyPath)) { throw new ArgumentNullException("inputAssemblyPath"); } if (string.IsNullOrWhiteSpace(outputAssemblyPath)) { throw new ArgumentNullException("outputAssemblyPath"); } // Mono.Cecil implementation has issues that if we directly pass file name for input assembly, // the assembly can't be overwritten if we give the same file name for output assembly, // So here we directly convert input assembly file to memory stream to ensure that input assembly file handle is release when outputing. var readerParameters = new ReaderParameters(); if (includeSymbol) { readerParameters.ReadSymbols = true; readerParameters.SymbolReaderProvider = new PdbReaderProvider(); readerParameters.SymbolStream = new MemoryStream(File.ReadAllBytes(Path.ChangeExtension(inputAssemblyPath, "pdb"))); } var assembly = AssemblyDefinition.ReadAssembly(new MemoryStream(File.ReadAllBytes(inputAssemblyPath)), readerParameters); var assemblyStatistics = StatisticsFactory.InitializeAssemblyWeavingRecord(assembly.FullName); try { foreach (var module in assembly.Modules) { var moduleStatistics = StatisticsFactory.InitializeModuleWeavingRecord(module.Name); var context = WeaverFactory.InitializeMethodWeavingContext(module); foreach (var clazz in module.GetTypes().Where(tp => tp.IsClass && (tp.HasMethods || tp.HasFields))) { // supporting data structure initialization. var classStatistics = StatisticsFactory.InitializeClassWeavingRecord(clazz.Name, clazz.FullName, clazz.Namespace); var switchHandlerBuilder = SwitchFactory.InitializeSwitchHandler(clazz, context.GetTypeReference(typeof(int))); var classCustomAttributes = GetClassCustomAttributes(clazz); var methodWeaver = new MethodWeaver(classCustomAttributes, context, switchHandlerBuilder); WeaveProperties(clazz, classCustomAttributes, methodWeaver, classStatistics); WeaveMethods(clazz, classCustomAttributes, methodWeaver, classStatistics); WeaveSwitches(switchHandlerBuilder.Build(), clazz, context, classStatistics); // handle statistics var classStatisticsFinished = classStatistics.Build(); if (classStatisticsFinished.WeavedMethodPropertyCount > 0) { moduleStatistics.AddClassWeavingStatistics(classStatisticsFinished); } } AddAssemblyReference(context, module, moduleStatistics); // handle statistics. var moduleStatisticsFinished = moduleStatistics.Build(); if (moduleStatisticsFinished.WeavedClassCount > 0) { assemblyStatistics.AddModuleWeavingStatistics(moduleStatisticsFinished); } } var writerParameters = new WriterParameters(); if (includeSymbol) { writerParameters.WriteSymbols = true; writerParameters.SymbolWriterProvider = new PdbWriterProvider(); } if (!string.IsNullOrWhiteSpace(strongNameKeyFile)) { writerParameters.StrongNameKeyPair = new StrongNameKeyPair(File.ReadAllBytes(strongNameKeyFile)); } assembly.Write(outputAssemblyPath, writerParameters); } catch (Exception e) { assemblyStatistics.Exception = e; } return(assemblyStatistics.Build()); }