C# 使用泛型和StructureMap实现策略模式
我正在尝试使用SM和泛型在我的存储库层中实现策略模式。为此,我有一个接口IPocoRepository,它有一个使用实体框架的具体实现。我已设法将其连接到我的引导程序文件中:C# 使用泛型和StructureMap实现策略模式,c#,generics,dependency-injection,structuremap,C#,Generics,Dependency Injection,Structuremap,我正在尝试使用SM和泛型在我的存储库层中实现策略模式。为此,我有一个接口IPocoRepository,它有一个使用实体框架的具体实现。我已设法将其连接到我的引导程序文件中: For(typeof(IPocoRepository<>)).Use(typeof(EntityFrameworkRepository<>)); For(typeof(IPocoRepository))。使用(typeof(EntityFrameworkRepository)); 当我尝试为这个
For(typeof(IPocoRepository<>)).Use(typeof(EntityFrameworkRepository<>));
For(typeof(IPocoRepository))。使用(typeof(EntityFrameworkRepository));
当我尝试为这个接口实现缓存时,问题出现了。在我的缓存类中,我需要一个基本存储库类的实例,这样我就可以保持我的设计干净利落。让我概述一下这三个文件的外观:
public interface IPocoRepository<T>
{
IQueryable<T> GetAll();
...
public class EntityFrameworkRepository<T> : IPocoRepository<T> where T : class
{
public IQueryable<T> GetAll()
{
...
public class CachedRepository<T> : IPocoRepository<T> where T : class
{
private IPocoRepository<T> _pocoRepository;
public CachedRepository(IPocoRepository<T> pr)
{
_pocoRepository = pr;
}
public IQueryable<T> GetAll()
{
var all = (IQueryable<T>)CacheProvider.Get(_cacheKey);
if (!CacheProvider.IsSet(_cacheKey))
{
all = _pocoRepository.GetAll();
...
公共接口IPocoRepository
{
IQueryable GetAll();
...
公共类EntityFrameworkRepository:IPocoRepository其中T:class
{
公共IQueryable GetAll()
{
...
公共类CachedRepository:IPocoRepository,其中T:class
{
私人IPocoRepository(私人IPocoRepository);;
公共缓存存储(IPocoreposition pr)
{
_pocoRepository=pr;
}
公共IQueryable GetAll()
{
var all=(IQueryable)CacheProvider.Get(_cacheKey);
如果(!CacheProvider.IsSet(_cacheKey))
{
all=_pocoRepository.GetAll();
...
编辑:我希望StructureMap在请求IPocoRepository时返回CachedPository,但在CachedPository中请求时除外-然后我希望它返回EntityFrameworkRepository
我知道这在处理非泛型类时很简单:
For<ICountyRepository>().Use<CachedCountyRepository>()
.Ctor<ICountyRepository>().Is<CountyRepository>();
For()。使用()
.Ctor().Is();
我试图在文档中搜索如何执行此操作,但找不到任何内容。如有任何帮助,将不胜感激!好的,这并不难。您可以使用类型拦截器。如果您有以下类:
public interface IRepository<T>{}
public class Repository<T>:IRepository<T>{}
public class RepositoryCache<T> : IRepository<T>
{
private readonly IRepository<T> _internalRepo;
public RepositoryCache(IRepository<T> internalRepo)
{
_internalRepo = internalRepo;
}
public IRepository<T> InternalRepo
{
get { return _internalRepo; }
}
}
公共接口IRepository{}
公共类存储库:IRepository{}
公共类RepositoryCache:IRepository
{
私人只读易趣回购;
公共回购缓存(IRepository internalRepo)
{
_内部回购=内部回购;
}
公开回购
{
获取{return\u internalRepo;}
}
}
然后您需要创建一个类型拦截器。您可以使用可配置的“MatchedTypeInterceptor”StructureMap为此提供。拦截器将需要查找您的存储库,然后确定泛型类型参数是什么。拥有类型参数后,它可以声明所需的缓存类型并对其进行初始化。作为初始化的一部分,它将在其构造函数中获取原始存储库。然后tor将把完成的缓存返回到ioc上下文请求的任何缓存
这可以移到您的注册表中,我只是把它作为一个简单的例子放在一起
[Test]
public void doTest()
{
MatchedTypeInterceptor interceptor = new MatchedTypeInterceptor(
x => x.FindFirstInterfaceThatCloses(typeof (IRepository<>)) != null);
interceptor.InterceptWith(original =>
{
Type closedType = original.GetType()
.FindFirstInterfaceThatCloses(typeof(IRepository<>));
var genericParameters = closedType.GetGenericArguments();
var closedCacheType = typeof(RepositoryCache<>)
.MakeGenericType(genericParameters);
return Activator.CreateInstance(closedCacheType, new[] {original});
});
ObjectFactory.Initialize(x =>
{
x.For(typeof (IRepository<>)).Use(typeof (Repository<>));
x.RegisterInterceptor(interceptor);
});
var test = ObjectFactory.GetInstance<IRepository<int>>();
Assert.That(test is RepositoryCache<int>);
}
[测试]
公共空间doTest()
{
MatchedTypeInterceptor拦截器=新的MatchedTypeInterceptor(
x=>x.FindFirstInterfaceThatCloses(typeof(IRepository))!=null;
interceptor.InterceptWith(原始=>
{
Type closedType=original.GetType()
.FindFirstInterfaceThatCloses(类型为(IRepository));
var genericParameters=closedType.GetGenericArguments();
var closedCacheType=typeof(RepositoryCache)
.MakeGenericType(genericParameters);
返回Activator.CreateInstance(closedCacheType,new[]{original});
});
ObjectFactory.Initialize(x=>
{
x、 用于(typeof(IRepository))。使用(typeof(Repository));
x、 注册接收器(拦截器);
});
var test=ObjectFactory.GetInstance();
断言(测试是RepositoryCache);
}
那么,实际的问题是什么呢?在我看来,你似乎在试图复制像Castle Windsor这样的框架。我已经更新了这个问题;希望能更清楚地说明我的问题。我希望坚持使用StructureMap这是依赖项注入框架所做的,看看吧-这可能会很有意义。:)Related:这篇文章可能会有帮助:干得好!我在代码中对_internalRepo字段进行了测试,它确实是存储库的一个实例——这正是我想要的!非常感谢!)