使用 WithConstructorArgument 并创建绑定类型

发布于 12-22 07:21 字数 1384 浏览 3 评论 0原文

我有一个如下所示的绑定:

kernel.Bind<IRepository<Holiday>>().To<RepositoryBase<Holiday>>();

问题是 RepositoryBase 采用称为 context 的 UnitOfWork 构造函数参数。这本身并不是一个问题。 Ninject 应该可以解决它。除了我有两个 UnitOfWork 实现之外,它们都使用属性鉴别器进行绑定。

kernel.Bind<IUnitOfWork>().To<MS_DevEntities>().WhenTargetHas<MsDataAttribute>()
    .InRequestScope();

如何指定在创建 IRepository 时应使用 MS_DevEntities 创建它?

当然,我可以这样做:

kernel.Bind<IRepository<Holiday>>().To<RepositoryBase<Holiday>>()
    .WithConstructorArgument("context", new MS_DevEntities());

但是,我更愿意让 Ninject 创建实例,特别是因为我正在使用 .InRequestScope() 生命周期。

有什么建议吗?

编辑:

以前,我使用的类看起来像这样:

public class HolidayRepository : RepositoryBase<Holiday>, IHolidayRepository
{
    public HolidayRepository([MsData]IUnitOfWork context) : base(context){}
}

但是,我现在发现自己有几十个这样的类,它们没有做太多事情,而是在我需要创建新存储库时添加额外的工作。我想直接将它们映射到绑定中。

EDIT2:

我想我可以做这样的事情,但这似乎有点黑客。有更好的办法吗?

kernel.Bind<MS_DevEntities>().ToSelf().InRequestScope();
kernel.Bind<IRepository<Holiday>>().To<RepositoryBase<Holiday>>()
    .WithConstructorArgument("context", 
        (context) => context.Kernel.Get<MS_DevEntities>());

I have a binding that looks like this:

kernel.Bind<IRepository<Holiday>>().To<RepositoryBase<Holiday>>();

The problem is that RepositoryBase takes a contructor paramter of UnitOfWork called context. This is not, in and of itself a problem. Ninject should resolve it. Except for the fact that I have two UnitOfWork implementations, both bound using an attribute discriminator.

kernel.Bind<IUnitOfWork>().To<MS_DevEntities>().WhenTargetHas<MsDataAttribute>()
    .InRequestScope();

How can specify that when an IRepository is created, it should be created with MS_DevEntities?

Certainly, i could do something like this:

kernel.Bind<IRepository<Holiday>>().To<RepositoryBase<Holiday>>()
    .WithConstructorArgument("context", new MS_DevEntities());

However, I would prefer to have Ninject create the instance, particularly because i'm using the .InRequestScope() lifecycle.

Any suggestions?

EDIT:

Previously, I was using a class that looked like this:

public class HolidayRepository : RepositoryBase<Holiday>, IHolidayRepository
{
    public HolidayRepository([MsData]IUnitOfWork context) : base(context){}
}

However, I now find myself with several dozen of these and they don't do much but add extra work when I need to create a new repository. I'd like to just map these directly in the bindings.

EDIT2:

I suppose I could do something like this, but it seems kind of hackish. Is there a better way?

kernel.Bind<MS_DevEntities>().ToSelf().InRequestScope();
kernel.Bind<IRepository<Holiday>>().To<RepositoryBase<Holiday>>()
    .WithConstructorArgument("context", 
        (context) => context.Kernel.Get<MS_DevEntities>());

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

贵在坚持2024-12-29 07:21:41

例如,将属性放入实体并使用如下内容:

kernel.Bind(typeof(IRepository<>)).To(typeof(RepositoryBase<>));
kernel.Bind<IUnitOfWork>().To<MS_DevEntities>()
      .When(r => EntityHas<MsData>(r));
kernel.Bind<IUnitOfWork>().To<TheOtherOne_DevEntities>()
      .When(r => EntityHas<TheOtherData>(r));

bool EntityHas<TAttribute>(IRequest r)
{
    return r.Target.Member.ReflectedType.IsGenericType &&
           r.Target.Member.ReflectedType.GetGenericArguments()[0]
               .GetCustomAttributes(typeof(TAttribute), false).Any();
}

您可以使用此 When 条件执行所有操作,并从 r.Target.Member.ReflectedType.GetGenericArguments()[0 获取实体类型] 查找您必须为此实体类型使用的 UoW。

使用配置的第二种方法

kernel.Bind<IUnitOfWork>().To<TheOtherOne_DevEntities>()
      .When(r => EntityNeedsUoW(r, 1));

bool EntityNeedsUoW(IRequest r, int id)
{
    return UoWConfig.GetDbIdForEntity(
         r.Target.Member.ReflectedType.GetGenericArguments()[0]) == id;
}

E.g. Put the attribute to the entity and use something like this:

kernel.Bind(typeof(IRepository<>)).To(typeof(RepositoryBase<>));
kernel.Bind<IUnitOfWork>().To<MS_DevEntities>()
      .When(r => EntityHas<MsData>(r));
kernel.Bind<IUnitOfWork>().To<TheOtherOne_DevEntities>()
      .When(r => EntityHas<TheOtherData>(r));

bool EntityHas<TAttribute>(IRequest r)
{
    return r.Target.Member.ReflectedType.IsGenericType &&
           r.Target.Member.ReflectedType.GetGenericArguments()[0]
               .GetCustomAttributes(typeof(TAttribute), false).Any();
}

You can do everything using this When condition and take the entity type from r.Target.Member.ReflectedType.GetGenericArguments()[0] to lookup somewhere which UoW that you have to use for this entity type.

2nd approch using config

kernel.Bind<IUnitOfWork>().To<TheOtherOne_DevEntities>()
      .When(r => EntityNeedsUoW(r, 1));

bool EntityNeedsUoW(IRequest r, int id)
{
    return UoWConfig.GetDbIdForEntity(
         r.Target.Member.ReflectedType.GetGenericArguments()[0]) == id;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文