2011-09-01 45 views
0

我有一種情況,當我使用派生類時,策略注入不再起作用。派生類中的統一攔截

的類參與這個樣子的(基本上是一個接口,一個抽象基類和實現類):

public interface IRepository<T> 
{ 
    void Create(T iItem); 
} 

public abstract class ElmtRepository<T> : IRepository<T> 
{ 
    protected List<T> Items { get; set; } 

    public ElmtRepository() 
    { 
     Items = new List<T>(); 
    } 

    public void Create(T iItem) 
    { 
     Items.Add(iItem); 
    } 
} 

public class AcctPgmRepository : ElmtRepository<AcctPgm> 
{ 
} 

的配置是這樣的:

<container> 
    <extension type="Interception"/> 
    <register type="IRepository[AcctPgm]" mapTo="AcctPgmRepository"> 
     <interceptor type="InterfaceInterceptor"/> 
     <interceptionBehavior type="PolicyInjectionBehavior"/> 
    </register> 
    <interception> 
     <policy name="policy-create"> 
     <matchingRule name="create-rule1" type="TypeMatchingRule"> 
      <constructor> 
      <param name="typeName"> 
       <value value="AcctPgmRepository"/> 
      </param> 
      </constructor> 
     </matchingRule> 
     <matchingRule name="create-rule2" type="MemberNameMatchingRule"> 
      <constructor> 
      <param name="namesToMatch"> 
       <array type="string[]"> 
       <value value="Create"/> 
       </array> 
      </param> 
      </constructor> 
     </matchingRule> 
     <callHandler name="create-handler1" type="AcctPgmAuthorizationHandler"> 
      <lifetime type="singleton"/> 
      <constructor> 
      <param name="allowedRoles"> 
       <array type="string[]"> 
       <value value="GroupController"/> 
       </array> 
      </param> 
      </constructor> 
     </callHandler> 
     </policy> 
    </interception> 
    </container> 

如果我刪除ElmtRepository基類,它按預期工作。對於基類,注入不會發生。沒有錯誤信息,但沒有政策。即使我在派生類中實現了Create()方法,也會發生這種情況。

有沒有辦法使這種類層次結構與Unity策略注入一起工作?

感謝, 吉姆

回答

2

這種類繼承的統一通常不會沒有問題。但是,配置泛型是無窮的頭痛與錯誤信息。我敢打賭,這是你真正的問題。但是,由於您沒有發佈錯誤消息(或AcctPgm類或AcctPgmAuthorizationHandler),我無法確定。

我改變所包含的類型int和得到這個版本的代碼工作的:

using System; 
using System.Collections.Generic; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using Microsoft.Practices.Unity.InterceptionExtension; 
using Microsoft.Practices.Unity; 
using Microsoft.Practices.Unity.Configuration; 

namespace UnityTest 
{ 
    public interface IRepository<T> 
    { 
     void Create(T iItem); 
    } 

    public abstract class ElmtRepository<T> : IRepository<T> 
    { 
     protected List<T> Items { get; set; } 

     public ElmtRepository() 
     { 
      Items = new List<T>(); 
     } 

     public void Create(T iItem) 
     { 
      System.Diagnostics.Debug.WriteLine("Creating..."); 
      Items.Add(iItem); 
     } 
    } 

    public class AcctPgmRepository : ElmtRepository<int> { } 

    public class LogHandler : ICallHandler 
    { 
     public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) 
     { 
      System.Diagnostics.Debug.WriteLine("Begin"); 
      IMethodReturn result = getNext().Invoke(input, getNext); 
      System.Diagnostics.Debug.WriteLine("End"); 
      return result; 
     } 
     public int Order { get; set; } 
    } 

    [TestClass] 
    public class InheritenceGenericsTests 
    { 
     [TestMethod] 
     public void CreateTest() 
     { 
      IUnityContainer container = new UnityContainer().LoadConfiguration("Inheritence"); 
      IRepository<int> r2 = container.Resolve<IRepository<int>>(); 
      Assert.IsNotNull(r2); 
      r2.Create(2); 
     } 
    } 
} 

與配置:

<alias alias="IRepository" type="UnityTest.IRepository`1, UnityTest"/> 
<alias alias="IRepositoryClosed" type="UnityTest.IRepository`1[System.Int32], UnityTest"/> 
<alias alias="AcctPgmRepository" type="UnityTest.AcctPgmRepository, UnityTest"/> 

<container name="Inheritence"> 
    <extension type="Interception"/> 
    <!-- register either type="IRepositoryClosed" or type="IRepository" --> 
    <register type="IRepositoryClosed" mapTo="AcctPgmRepository"> 
    <interceptor type="InterfaceInterceptor"/> 
    <policyInjection/> 
    </register> 
    <interception> 
    <policy name="policy-create"> 
     <matchingRule name="create-rule2" type="MemberNameMatchingRule"> 
     <constructor> 
      <param name="namesToMatch"> 
      <array type="string[]"> 
       <value value="Create"/> 
      </array> 
      </param> 
     </constructor> 
     </matchingRule> 
     <callHandler name="create-handler1" type="UnityTest.LogHandler, UnityTest"></callHandler> 
    </policy> 
    </interception> 
</container> 

給出輸出:

Begin 
Creating... 
End 
+0

謝謝您的回答。我使用的解決方案是刪除基類。我想知道是否你使用了「IRepository'1」,這有所作爲。我沒有看到太多改變,否則? – Migdalin

+0

沒有「'1」,它絕對不能工作。你是對的,我沒有太多變化。 – ErnieL