public MethodDecoratorBase( IAssemblyResolver resolver, CilGraphGetter graphGetter, Delegate sourceDecorationDelegate, Func <string, string> decorationNameGenerator) { Contract.Requires(resolver != null); Contract.Requires(graphGetter != null); Contract.Requires(sourceDecorationDelegate != null); Contract.Ensures(this.Resolver != null); Contract.Ensures(this.SourceDecorationAssembly != null); Contract.Ensures(this.GraphGetter != null); Contract.Ensures(this.SourceDecoration != null); Contract.Ensures(this.TargetDecorationNameGenerator == null); // TODO could probably allow instance decorations for instance targets without any real trouble since required state would be cloned over if (!sourceDecorationDelegate.Method.IsStatic) { throw new ArgumentException("Decoration methods must be static.", nameof(sourceDecorationDelegate)); } this.Resolver = resolver; this.SourceDecorationAssembly = resolver.Resolve(AssemblyNameReference.Parse(sourceDecorationDelegate.Method.Module.Assembly.FullName)); this.SourceDecoration = this.SourceDecorationAssembly.MainModule.ImportReference(sourceDecorationDelegate.Method).Resolve(); this.GraphGetter = graphGetter; this.TargetDecorationNameGenerator = decorationNameGenerator ?? (name => name); }
/// <summary> /// Executes the interface mixin command using the arguments passed into the constuctor. /// </summary> public void Execute() { this.Target.Interfaces.Add(this.Target.Module.Import(this.InterfaceType)); try { var graph = new CilGraphGetter().Get(this.Source); new CloningContext(graph, this.Source, this.Target).Execute(); } catch (InvalidOperationException e) { throw new WeavingException(e.Message, e); } }
/// <summary> /// Introduces a type into an assembly that will be cloned from a source type. /// </summary> /// <param name="graphGetter">Allows a source IL graph to be retrieved</param> /// <param name="sourceType">Source type from which the clone into the target assembly</param> /// <param name="targetTypeNamespace">Namespace of the introduced type. Defaults to the namespace of <paramref name="sourceType"/>.</param> /// <param name="targetTypeName">Name of the introduced type. Defaults to the name of <paramref name="sourceType"/>.</param> public TypeIntroduction(CilGraphGetter graphGetter, TypeDefinition sourceType, string targetTypeNamespace = null, string targetTypeName = null) { Contract.Requires(graphGetter != null); Contract.Requires(sourceType != null); Contract.Requires(targetTypeNamespace == null || !string.IsNullOrWhiteSpace(targetTypeNamespace)); Contract.Ensures(this.GraphGetter != null); Contract.Ensures(this.SourceType != null); Contract.Ensures(this.TargetTypeNamespace != null); Contract.Ensures(!string.IsNullOrWhiteSpace(this.TargetTypeName)); this.GraphGetter = graphGetter; this.SourceType = sourceType; this.TargetTypeNamespace = targetTypeNamespace ?? sourceType.Namespace; this.TargetTypeName = targetTypeName ?? sourceType.Name; }
public void OneTimeSetUp() { using (var resolver = new DefaultAssemblyResolver()) using (var targetAssembly = resolver.Resolve(AssemblyNameReference.Parse("Cilador.TestAopTarget"), new ReaderParameters { ReadWrite = true })) { var loom = new Loom(); var graphGetter = new CilGraphGetter(); using (var runWithoutReplacementDecoration = new ActionDecorator <string[]>(resolver, graphGetter, RunWithoutReplacementDecoration, name => $"{name}_Decorated")) using (var runWithReplacementDecorator = new ActionDecorator <string>(resolver, graphGetter, RunWithReplacementDecorator)) { loom.WeavableConcepts.Add(new WeavableConcept <MethodDefinition>(new PointCut <MethodDefinition>(m => m.Name == "RunWithoutReplacement"), runWithoutReplacementDecoration)); loom.WeavableConcepts.Add(new WeavableConcept <MethodDefinition>(new PointCut <MethodDefinition>(m => m.Name == "RunWithReplacement"), runWithReplacementDecorator)); loom.Weave(targetAssembly); } targetAssembly.Write(); } }
public void CanIntroduceEnumToAssembly() { using (var resolver = new DefaultAssemblyResolver()) using (var targetAssembly = resolver.Resolve(AssemblyNameReference.Parse("Cilador.TestAopTarget"), new ReaderParameters { ReadWrite = true })) { TypeDefinition sourceType; using (var sourceAssembly = resolver.Resolve(AssemblyNameReference.Parse(typeof(Status).Assembly.FullName))) { sourceType = sourceAssembly.MainModule.GetType(typeof(Status).FullName); var loom = new Loom(); var graphGetter = new CilGraphGetter(); using (var introduction = new TypeIntroduction(graphGetter, sourceType, "Cilador.TestAopTarget")) { loom.WeavableConcepts.Add(new WeavableConcept <ModuleDefinition>(new PointCut <ModuleDefinition>(m => m.IsMain), introduction)); loom.Weave(targetAssembly); } } targetAssembly.Write(); } }
public void Weave(AssemblyDefinition targetAssembly, IAssemblyResolver resolver = null, CilGraphGetter graphGetter = null) { resolver = resolver ?? targetAssembly.MainModule.AssemblyResolver; graphGetter = graphGetter ?? new CilGraphGetter(); var sourceGraph = graphGetter.Get(targetAssembly); foreach (var concept in this.WeavableConcepts) { concept.Weave(sourceGraph); } }