将Unity拦截挂钩到没有参数的方法

时间:2016-07-26 23:11:26

标签: c# unity-container

我正在研究使用Unity的概念证明,我遇到了拦截器被调用的问题。我正在使用政策注入。

所以这里有一些代码

建立团结:

 private void ApplyCrossCuttingConcerns(UnityContainer container)
    {
        container.AddNewExtension<Interception>();

        container.RegisterType<IContact, Contact>(
            new InterceptionBehavior<PolicyInjectionBehavior>(),
            new Interceptor<InterfaceInterceptor>());
        container.Configure<Interception>()
            .AddPolicy("extensionPolicy")
            .AddMatchingRule<TypeMatchingRule>(new InjectionConstructor(typeof(Contact).ToString()))
            .AddMatchingRule<MethodSignatureMatchingRule>(new InjectionConstructor("Save",new [] {""},true))
            .AddCallHandler<ExtensionHandler>(new ContainerControlledLifetimeManager(), new InjectionConstructor());

    }

我从BussinessObject继承的联系类,其中有问题的方法存在

 public class Contact : BussinessObject, IContact
{...}

 public abstract class BussinessObject
{
    #region Local Vars
    protected readonly IRepository _repository;
    protected bool isNew;
    #endregion Local Vars

    #region Properties
    /// <summary>
    /// Gets or sets a value indicating whether this instance is new.
    /// </summary>
    /// <value>
    /// <see langword="true" /> if this instance is new; otherwise, <see langword="false" />.
    /// </value>
    internal bool IsNew { get { return (isNew); } set { isNew = value; } }
    #endregion

    #region Constructors

    /// <summary>
    /// Initializes a new instance of the <see cref="BussinessObject"/> class.
    /// </summary>
    /// <param name="repository">The repository.</param>
    public BussinessObject(IRepository repository)
    {
        if (repository.IsEmpty())
        {
            throw new Exception("The repository is a maditory parameter for a bussiness object");
        }
        _repository = repository;
    }

    #endregion Constructors

    #region Methods

    #region public

    /// <summary>
    /// Saves this instance.
    /// </summary>
    public virtual void Save()
    {
        Validate();
        SetIdenity();
        if (isNew)
        {
            Insert();
        }
        else
        {
            Update();
        }
        isNew = false;
    }

    /// <summary>
    /// Permantlies the remove from system.
    /// </summary>
    /// <param name="ID">The identifier.</param>
    public abstract void PermantlyRemoveFromSystem(Guid id);

    #endregion public

    #region Internal

    /// <summary>
    /// Sets the idenity.
    /// </summary>
    internal abstract void SetIdenity();

    #endregion Internal

    #region protected

    /// <summary>
    /// Commons the initialize.
    /// </summary>
    protected virtual void CommonInit()
    {
        isNew = false;
    }

    /// <summary>
    /// Inserts this instance.
    /// </summary>
    protected abstract void Insert();

    /// <summary>
    /// Updates this instance.
    /// </summary>
    protected abstract void Update();

    /// <summary>
    /// Validates this instance.
    /// </summary>
    protected abstract void Validate();

    #endregion protected

    #endregion
}

现在IContact

public interface IContact : DTO.IContact
{
    void Save();
    void Delete();

    #region Phone Number Manipulation

    bool SetDefaultNumber(PhoneNumber phNum);
    PhoneNumber GetDefaultNumber();
    bool HasDefaultNumber();
    PhoneNumber[] GetPhoneNumbers();
    PhoneNumber[] GetPhoneNumbers(bool includeDeleted);
    void AddPhoneNumber(PhoneNumber phToAdd);
    bool RemovePhoneNumber(PhoneNumber phToRemove);
    #endregion

    #region Email Address Manipulation

    bool SetDefaultEMailAddress(EmailAddress emAdd);
    bool HasDefaultEmailAddress();
    EmailAddress[] GetAllEmailAddresses();
    EmailAddress[] GetAllEmailAddresses(bool includeDeleted);
    EmailAddress AddEmailAddress(string addressToAdd);
    EmailAddress GetDefaultEMailAddress();

    #endregion

    #region Snailmail Address Manipulation

    bool SetDefaultAddress(SnailMailAddress ad);
    SnailMailAddress GetDefaultAddress();
    bool HasDefaultAddress();
    SnailMailAddress[] GetAllAddresses();
    SnailMailAddress[] GetAllAddresses(bool includeDeleted);
    void AddAddress(SnailMailAddress adToAdd);
    bool RemoveAddress(SnailMailAddress adToRemove);

    #endregion

}

最后是extensionHandler

 public class ExtensionHandler : ICallHandler
{
    public int Order { get; set; }

    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        //going to do our work before we pass on to the next item in the pipeline
        SomeFunctionality handlerFunctionality = new SomeFunctionality();
        handlerFunctionality.PreformWork();

        //pass on to the next item in the pipeline
        var result = getNext().Invoke(input, getNext);


        //we can put post processing logic in here


        return result;
    }

我设置了一个测试来解析联系对象,然后在其上设置数据并调用save方法。我在ExtensionHandler的invoke方法的顶部有一个断点,但我从来没有到达那里。我认为我配置MethodSignatureMatchingRule的方式存在问题,但我还没有在网上找到文档,显示拦截的示例被配置为没有参数的方法。

任何帮助都会得到帮助

1 个答案:

答案 0 :(得分:0)

经过一些实验,我找到了答案 此问题出现在匹配规则中 这两个规则的正确代码都不正确如下:

private void ApplyCrossCuttingConcerns(UnityContainer container)
    {
        container.AddNewExtension<Interception>();

        container.RegisterType<IContact, Contact>(
            new InterceptionBehavior<PolicyInjectionBehavior>(),
            new Interceptor<InterfaceInterceptor>());
        container.Configure<Interception>()
            .AddPolicy("extensionPolicy")
            .AddMatchingRule<TypeMatchingRule>(new InjectionConstructor(new InjectionParameter(typeof(IContact))))
            .AddMatchingRule<MemberNameMatchingRule>(new InjectionConstructor(new InjectionParameter("Save")))
            .AddCallHandler<ExtensionHandler>(new ContainerControlledLifetimeManager(), new InjectionConstructor());

    }