2017-07-18 108 views
0

上根据控制器上的属性解决依赖关系我试图尽可能轻松地在ASP.NET Core MVC项目的数据访问层中实现缓存。主要问题是我们不希望从所有页面上的缓存中读取,只有一部分。下面的例子应该说明了这种设置,我们有:如何在ASP.NET Core MVC

[UseCache] 
public class ControllerA : Controller 
{ 
    public ControllerA(IBuilder builder) 
    { 
     // Should resolve an IBuilder with a CacheService 
    } 
} 

public class ControllerB : Controller 
{ 
    public ControllerB(IBuilder builder) 
    { 
     // Should resolve an IBuilder with a NullCacheService 
    } 
} 

public class Builder : IBuilder 
{ 
    public Builder(ICacheService cacheService) 
    { 
     // The type of the resolved ICacheService depends on the UseCache 
     // attribute on any of the object that depends on this IBuilder 
    } 
} 

public class CacheService : ICacheService 
{ 
    public Object Get(string key, Func<Object> getValue) 
    { 
     // Check if the value is cached against Key and return it if it's not 
     // Obviously needs a lot more here regarding caching timeframes, expiry etc 
    } 
} 

public class NullCacheService : ICacheService 
{ 
    public Object Get(string key, Func<Object> getValue) 
    { 
     // Don't do anything with key, just do the work in getValue and return it 
    } 
} 

public class UseCacheAttribute : Attribute 
{ 

} 

我知道Autofac can deal with resolving dependencies using attributes

  1. 的Autofac.Extras.AttributeMetadata包未在ASP.NET MVC核心

  2. 支持

    即使它受到支持,我也看不到它将如何支持包含此对象的对象的属性检测。

我很高兴介绍一个新的IoC框架,我们并不依赖于Autofac或默认的IoC实现。

是我想要实现的可能吗?什么会被认为是更好的缓存解决方案?

+0

根据[Autofac.Extras.AttributeMetadata v4.0.1发行说明](https://github.com/autofac/Autofac.Extras.AttributeMetadata/releases/tag/v4.0.1),您可以使用Autofac.Features。 .net核心支持的AttributeFilters'。 – Sakis

+0

@Sakis这是真的,但不允许你使用你自己的属性,据我所知 - 这需要你注册AttributedMetadataModule [在Autofac.Extras.AttributeMetadata中](https://autofac.org/apidoc /html/D6EFF2D8.htm),这不会被移植到.NET Core。 –

回答

1

我很高兴介绍一个新的IoC框架,我们并不依赖于Autofac或默认的IoC实现。

我没那么熟悉Autofac,但我熟悉简单的喷油器,这样我就可以告诉你如何用简单的注射器申请此类注册:

var cache = new CacheService(); 
container.RegisterConditional(typeof(IBuilder), 
    Lifestyle.Transient.CreateRegistration<Builder>(
     () => new Builder(cache), 
     container), 
    c => c.Consumer.ImplementationType.GetCustomAttribute<UseCacheAttribute>() != null); 

container.RegisterConditional(typeof(IBuilder), 
    Lifestyle.Transient.CreateRegistration<Builder>(
     () => new Builder(new NullCacheService()), 
     container), 
    c => !c.Handled); 

这个注册是有点复杂因为您希望基于Builder的消费者更改Builder类型的依赖关系。寻找消费者消费者的'连锁店'是简单注射器不支持的,因为它很容易导致不正确的行为,特别是当中等消费者的生活方式不是短暂的时候。这是条件注册是IBuilder而不是ICacheService

+0

这看起来像我们要实现它的方式。我目前无法验证这项工作(我遇到了使用ASP.NET Core Identity工作的Simple Injector的crosswire方法的问题),但它看起来应该起作用。谢谢!如果我有任何问题,我会报告回来;) –

+0

在文档中有一些关于交叉连接身份信息的信息:https://simpleinjector.org/aspnetcore#working-with-asp-net-core-identity。如果您有任何特别的问题,您可能需要发布一个新的问题[这里](https://github.com/simpleinjector/SimpleInjector/issues/new)或[here](https://stackoverflow.com/questions /问)。 – Steven

+0

该指南非常简单,它并不能真正解释交叉布线。我无法在CrossWire的文档中找到任何内容。这很重要,因为我有一个自定义的实现,我真的不想连接所有的身份依赖关系......将在其他地方提问:) –