Перехват единства в производном классе
У меня есть ситуация, когда внедрение политики больше не работает, когда я использую производный класс.
Используемые классы выглядят следующим образом (в основном интерфейс, абстрактный базовый класс и класс реализации):
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?
Спасибо джим
1 ответ
Этот тип наследования классов Unity обычно обходится без проблем. Однако настройка обобщенных шаблонов - это бесконечные головные боли с плохими сообщениями об ошибках. Держу пари, это твоя настоящая проблема. Однако, поскольку вы не опубликовали свое сообщение об ошибке (или класс 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