/// <summary> /// Initializes a new instance. /// </summary> /// <param name="obj">The S# object the method belongs to.</param> /// <param name="method">The CLR method the metadata should be provided for.</param> /// <param name="name">The name of the method; if <c>null</c>, the method's CLR name is used.</param> /// <param name="baseMethod">The overridden base method, if any.</param> internal MethodMetadata(IMetadataObject obj, MethodInfo method, string name = null, MethodMetadata baseMethod = null) { Requires.NotNull(obj, () => obj); Requires.NotNull(method, () => method); Requires.That(name == null || !String.IsNullOrWhiteSpace(name), () => name, "The name must be null or non-whitespace only."); Requires.That(baseMethod == null || method != baseMethod.MethodInfo, "A method cannot override itself."); Requires.That(baseMethod == null || obj == baseMethod._object, "The base method must belong to the same object."); Requires.That(baseMethod == null || baseMethod.OverridingMethod == null, "The base method has already been overridden."); _object = obj; Name = EscapeName(name ?? method.Name); MethodInfo = method; BaseMethod = baseMethod; if (baseMethod != null) baseMethod.OverridingMethod = this; var backingFieldAttribute = MethodInfo.GetCustomAttribute<BackingFieldAttribute>(); if (backingFieldAttribute != null) BackingField = backingFieldAttribute.GetFieldInfo(MethodInfo.DeclaringType); var behaviorAttribute = MethodInfo.GetCustomAttribute<IntendedBehaviorAttribute>(); if (behaviorAttribute != null) IntendedBehavior = behaviorAttribute.GetMethodInfo(MethodInfo.DeclaringType); if (backingFieldAttribute == null && behaviorAttribute == null) IntendedBehavior = MethodInfo; Behaviors = new MethodBehaviorCollection(obj, this); ImplementedMethods = DetermineImplementedInterfaceMethods().ToArray(); _methodBody = new Lazy<MethodBodyMetadata>(InitializeMethodBody); }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="obj">The S# object the method belongs to.</param> /// <param name="method">The metadata of the method the behavior belongs to.</param> internal FaultInjection(IMetadataObject obj, MethodMetadata method) { Requires.NotNull(obj, () => obj); Requires.NotNull(method, () => method); _object = obj; Method = method; }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="obj">The S# object the method belongs to.</param> /// <param name="method">The metadata of the method the behavior belongs to.</param> public IntendedBehavior(object obj, MethodMetadata method) { Requires.NotNull(obj, () => obj); Requires.NotNull(method, () => method); Method = method; _object = obj; }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="obj">The S# object the affected method belongs to.</param> /// <param name="affectedMethod">The metadata of the S# method that should be affected by the fault injector.</param> internal MethodBehaviorCollection(IMetadataObject obj, MethodMetadata affectedMethod) { Requires.NotNull(obj, () => obj); Requires.NotNull(affectedMethod, () => affectedMethod); _object = obj; AffectedMethod = affectedMethod; FaultEffects = Enumerable.Empty<FaultEffectMetadata>(); FaultInjections = Enumerable.Empty<FaultInjection>().ToArray(); // Create and inject the intended behavior now; we do that as early as possible so that all // methods can be called reliably in the model initialization phase IntendedBehavior = new IntendedBehavior(_object, affectedMethod); IntendedBehavior.Bind(); }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="component">The component the method belongs to.</param> /// <param name="port">The CLR method representing the component's port.</param> /// <param name="name">The name of the port; if <c>null</c>, the port's CLR name is used.</param> /// <param name="basePort">The overridden base port, if any.</param> public ProvidedPortMetadata(Component component, MethodInfo port, string name = null, MethodMetadata basePort = null) : base(component, port, name, basePort) { Requires.That(HasImplementation, () => port, "Provided ports must have an implementation."); Requires.That(CanBeAffectedByFaultEffects, () => port, "Provided ports must be sensitive to fault effects."); _boundRequiredPorts = new Lazy<IEnumerable<RequiredPortMetadata>>(() => Bindings.Select(binding => binding.RequiredPort)); _bindings = new Lazy<IEnumerable<BindingMetadata>>(() => { var bindings = new List<BindingMetadata>(); DeclaringObject.RootComponent.VisitPreOrder( metadata => bindings.AddRange(metadata.Bindings.Where(binding => binding.ProvidedPort == this))); return bindings; }); }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="obj">The S# object the method belongs to.</param> /// <param name="method">The metadata of the method the fault injection belongs to.</param> /// <param name="faultEffect">The fault effect that should be injected deterministically.</param> public DeterministicFaultInjection(IMetadataObject obj, MethodMetadata method, FaultEffectMetadata faultEffect) : base(obj, method) { Requires.NotNull(faultEffect, () => faultEffect); FaultEffect = faultEffect; }