如何使用内置的Funq容器正确注入依赖项?

时间:2013-04-10 07:18:22

标签: asp.net servicestack

我有一个缓存的存储库

public interface IRepository
{
    void LogWebUsage(string html);
    IEnumerable<ApiKey> GetApiKeys();
    ApiKey GetApiKey(Guid key);
}

public class Repository : IRepository
{
    private static readonly ILog Log = LogManager.GetLogger("API.Repository");

    public IDbConnectionFactory DbFactory { get; set; }

    public void LogWebUsage(string request)
    {
        Log.Debug(request);
    }

    public virtual IEnumerable<ApiKey> GetApiKeys()
    {
        List<ApiKey> result = null;
        using (var db = DbFactory.OpenDbConnection())
        {
            result = db.SelectParam<ApiKey>(q => q.Active);
        }

        return result;
    }

    public ApiKey GetApiKey(Guid key)
    {
        ApiKey result = null;
        using (var db = DbFactory.OpenDbConnection())
        {
            result = (db.SelectParam<ApiKey>(q => q.Id == key)).FirstOrDefault();
        }

        return result;
    }
}

public class CachedRepository : Repository
{
    public ICacheClient Cache { get; set; }

    public override IEnumerable<ApiKey> GetApiKeys()
    {
        const string cacheKey = "GetApiKeys";

        var result = Cache.Get<IEnumerable<ApiKey>>(cacheKey);

        if (result == null)
        {
            result = base.GetApiKeys();

            if (result.Any())
            {
                Cache.Add(cacheKey, result, TimeSpan.FromMinutes(30));
            }
        }
        return result;
    }
}

我这样配置它。

//Register any dependencies you want injected into your services
container.Register<IDbConnectionFactory>(new OrmLiteConnectionFactory(ConfigUtils.GetConnectionString("DBConnstr"), true, SqlServerOrmLiteDialectProvider.Instance));
container.Register<ICacheClient>(new MemoryCacheClient());
container.Register<IRepository>(new CachedRepository());
container.RegisterAutoWired<CachedRepository>();

所以我希望的是IDbConnectionFactory和ICacheClient都会在运行时注入,但它们都是null。如何正确地考虑这种类型的依赖图?

谢谢你, 斯蒂芬

更新

谷歌搜索了几个小时后,我终于找到了一个有效的解决方案。构造函数通过配置注入。

public class CachedRepository : Repository
{
    private ICacheClient Cache { get; set; }

    public CachedRepository(IDbConnectionFactory dbFactory, ICacheClient cache) : base(dbFactory)
    {
        Cache = cache;
    }

    public override IEnumerable<ApiKey> GetApiKeys()
    {
        const string cacheKey = "GetApiKeys";

        var result = Cache.Get<IEnumerable<ApiKey>>(cacheKey);

        if (result == null)
        {
            result = base.GetApiKeys();

            if (result.Any())
            {
                Cache.Add(cacheKey, result, TimeSpan.FromMinutes(30));
            }
        }
        return result;
    }
}

配置

//Register any dependencies you want injected into your services
container.Register<IDbConnectionFactory>(c => new OrmLiteConnectionFactory(ConfigUtils.GetConnectionString("DBConnstr"), true, SqlServerOrmLiteDialectProvider.Instance));        
container.Register<ICacheClient>(c => new MemoryCacheClient());
container.Register<IRepository>(c => new CachedRepository(c.Resolve<IDbConnectionFactory>(), c.Resolve<ICacheClient>()));

它有效,但我仍然想知道如何连接属性注入。

保重, 斯蒂芬......再次

1 个答案:

答案 0 :(得分:4)

AutoWiring in ServiceStack's Funq IOC are here的API:

使用通用API:

container.RegisterAutoWired<MyType>();
container.RegisterAutoWiredAs<MyType,IMyType>();

使用运行时类型的API:

container.RegisterAutoWiredType(typeof(MyType));
container.RegisterAutoWiredType(typeof(MyType),typeof(IMyType));
container.RegisterAutoWiredTypes(typeof(MyType),typeof(MyType2),typeof(MyType3));

基本上,您可以使用上述任何API来自动连接您的依赖项,例如:

container.Register<IDbConnectionFactory>(c => new 
  OrmLiteConnectionFactory(ConfigUtils.GetConnectionString("DBConnstr"), true, 
  SqlServerDialect.Provider));        

container.Register<ICacheClient>(c => new MemoryCacheClient());
container.RegisterAutoWiredAs<CachedRepository,IRepository>(); //auto-wired