/// <summary> /// Initializes a new instance of the <see cref="DelegateTarget" /> class. /// </summary> /// <param name="factory">Required - the factory delegate. Must have a return type and can take /// 0 or more parameters.</param> /// <param name="declaredType">Optional - type that will be set into the <see cref="DeclaredType" /> for the target; /// if not provided, then it will be derived from the <paramref name="factory" />'s return type</param> /// <param name="scopeBehaviour">Scope behaviour for this delegate. The default is <see cref="ScopeBehaviour.Implicit"/>, which means /// that that any returned instance will be tracked implicitly by the active scope. If the delegate produces a new instance, then /// this or <see cref="ScopeBehaviour.Explicit"/> can be used safely - the choice being whether /// the expression should produce one instance per scope, or should act as a disposable transient object.</param> /// <param name="scopePreference">If <paramref name="scopeBehaviour"/> is not <see cref="ScopeBehaviour.None"/>, then this controls /// the preferred scope for the instance to be tracked. Defaults to <see cref="ScopePreference.Current"/></param> /// <exception cref="ArgumentException">If the <paramref name="factory" /> represents a void delegate or if /// <paramref name="declaredType" /> is passed but the type is not compatible with the return type of /// <paramref name="factory" />.</exception> /// <exception cref="ArgumentNullException">If <paramref name="factory" /> is null</exception> public DelegateTarget( Delegate factory, Type declaredType = null, ScopeBehaviour scopeBehaviour = ScopeBehaviour.Implicit, ScopePreference scopePreference = ScopePreference.Current) { if (factory == null) { throw new ArgumentNullException(nameof(factory)); } FactoryMethod = factory.GetMethodInfo(); if (FactoryMethod.ReturnType == typeof(void)) { throw new ArgumentException("Factory must have a return type", nameof(factory)); } if (FactoryMethod.GetParameters().Any(p => p.ParameterType.IsByRef)) { throw new ArgumentException("Delegates which have ref or out parameters are not permitted as the factory argument", nameof(factory)); } if (declaredType != null) { if (!TypeHelpers.AreCompatible(FactoryMethod.ReturnType, declaredType) && !TypeHelpers.AreCompatible(declaredType, FactoryMethod.ReturnType)) { throw new ArgumentException(string.Format(ExceptionResources.DeclaredTypeIsNotCompatible_Format, declaredType, FactoryMethod.ReturnType), nameof(declaredType)); } } this._declaredType = declaredType; this._scopeBehaviour = scopeBehaviour; this._scopePreference = scopePreference; Factory = factory; }
public NullaryDelegateTarget( Delegate factory, Type declaredType = null, ScopeBehaviour scopeBehaviour = ScopeBehaviour.Implicit, ScopePreference scopePreference = ScopePreference.Current) : base(factory, declaredType, scopeBehaviour, scopePreference) { if (FactoryMethod.GetParameters()?.Length > 0) { throw new ArgumentException("Only nullary delegates (i.e. which have no parameters) can be used for this target"); } this._strongDelegate = Expression.Lambda <Func <object> >(Expression.Convert( Expression.Invoke(Expression.Constant(factory)), typeof(object))).Compile(); }