Ninject 2.0:无属性的属性注入

发布于 2024-09-09 07:02:46 字数 163 浏览 6 评论 0原文

有没有办法在 Ninject 2 中使用属性注入而不使用 [Inject] 属性?这会在将使用它进行连接的类中创建对 Ninject 的依赖关系,并且我更喜欢避免对 IoC 容器产生不必要的依赖关系,这就是我最终更频繁地使用构造函数注入的原因。

我想这同样适用于方法注入

Is there a way to use Property Injection in Ninject 2 without using the [Inject] attribute? This creates a dependency to Ninject in the class that will be wired using it and I prefer to avoid having unneeded dependencies to my IoC container, that's why I end up using Constructor Injection more often.

I guess the same applies to Method Injection

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

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

发布评论

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

评论(3

红衣飘飘貌似仙 2024-09-16 07:02:46

我按照 Ruben 的提示发布了一个小 关于如何实现此目的的博客文章,但这里是快速答案:

创建自定义属性:

public class InjectHereAttribute : Attribute
{
}

目标类现在将如下所示:

public class Samurai
{
    [InjectHere]        
    public IWeapon Context { get; set; }
}

现在 Ninject 必须配置为使用自定义属性,这可以通过创建识别自定义属性的 IInjectionHeuristic 实现来完成:

public class CustomInjectionHeuristic : NinjectComponent, IInjectionHeuristic, INinjectComponent, IDisposable
{
    public new bool ShouldInject(MemberInfo member)
    {
        return member.IsDefined(
          typeof(InjectHereAttribute),
          true);
    }
}

最后使用 Components 集合将此行为添加到 Ninject Kernel,它将沿着现有组件运行,即默认实现IInjectionHeuristic,这意味着可以使用默认属性或自定义属性。

// Add custom inject heuristic
kernel.Components.Add<IInjectionHeuristic, CustomInjectionHeuristic>();

I followed Ruben's tip and posted a small blog post on how to achieve this, but here's the quick answer:

Create a custom attribute:

public class InjectHereAttribute : Attribute
{
}

The target class will now look like this:

public class Samurai
{
    [InjectHere]        
    public IWeapon Context { get; set; }
}

Now Ninject must be configured to use the custom attribute, this can be done by creating an implementation of IInjectionHeuristic that recognizes the custom attribute:

public class CustomInjectionHeuristic : NinjectComponent, IInjectionHeuristic, INinjectComponent, IDisposable
{
    public new bool ShouldInject(MemberInfo member)
    {
        return member.IsDefined(
          typeof(InjectHereAttribute),
          true);
    }
}

And finally add this behavior to the Ninject Kernel using the Components collection, it will run along the existing components, namely the default implementation of IInjectionHeuristic, which means either the default or the custom attribute can be used.

// Add custom inject heuristic
kernel.Components.Add<IInjectionHeuristic, CustomInjectionHeuristic>();
天生の放荡 2024-09-16 07:02:46

您可以在创建时将另一个 [attribute] 类型传递给内核,该类型可以用来代替 InjectAttribute,但您仍然需要集中引用 OOTB 的内容。

最近有一个类似的问题,关于在没有属性的情况下进行 PI - 没有 OOTB(直接在流畅的配置界面上)来放入自定义扫描仪,但可扩展性点(在构建您的应用程序时添加一个实现 Ninject 接口的组件)如果寻找给定的属性不是您想要的,则指示该方面如何工作的内核将根据约定优于配置来确定注入位置 - 没有什么可以阻止您将扫描修改为仅基于属性名称(因此它不一定必须位于中心位置)。

请注意,一般来说,构造函数注入有很多好处,包括这一点,并且让您的代码与容器无关非常重要(即使您目前对此感到满意!)

You can pass in another [attribute] type to the Kernel upon creation which can be used instead of InjectAttribute, but you'll still have to reference something centrally OOTB.

There was a similar question very recently about doing PI without attributes - there's no OOTB (as in directly on the fluent configuration interface) to put in a custom scanner but the extensibility points (you add a component that implements a Ninject interface as you build your Kernel that dictates how that aspect is to be work if looking for a given attribute isnt't what you want) are in there to determine where to inject based on Convention over Configuration - there's nothing stopping you amending the scanning to be based on just an attribute name (so it doesnt necessarily have to live in a central location).

Note that, in general, constructor injection is good for lots of reasons anyway, including this one, and keeping you code container agnostic is important (even if you're currently happy with one!)

李不 2024-09-16 07:02:46

我能够使用启发式类来完成此操作:

public sealed class MyInjectionHeuristic : NinjectComponent, IInjectionHeuristic
{
        private static readonly IList<Type> 
            _propertyInjectible = 
                new List<Type>
                {
             typeof(IMyService),
                };

                    /// <summary>
      /// Returns a value indicating whether the specified member should be injected.
      /// </summary>
      /// <param name="member">The member in question.</param>
      /// <returns><c>True</c> if the member should be injected; otherwise <c>false</c>.</returns>
      public bool ShouldInject(MemberInfo member)
      {
       var info = member as PropertyInfo;

       if( member == null || info == null )
        return false;

       if (info.CanWrite)
        return _propertyInjectible.Contains(info.PropertyType);

       if( this.Settings == null )
        return false;

       var propList = member.GetCustomAttributes(this.Settings.InjectAttribute, true);

       return propList.Length > 0;
      }
}

创建内核时:

var heuristics = _kernel.Components.Get<ISelector>().InjectionHeuristics;
   heuristics.Add(new MyInjectionHeuristic());

当您想通过属性注入其他类型时,只需将其他类型添加到 IList 即可。

I was able to accomplish this using a Heuristic class:

public sealed class MyInjectionHeuristic : NinjectComponent, IInjectionHeuristic
{
        private static readonly IList<Type> 
            _propertyInjectible = 
                new List<Type>
                {
             typeof(IMyService),
                };

                    /// <summary>
      /// Returns a value indicating whether the specified member should be injected.
      /// </summary>
      /// <param name="member">The member in question.</param>
      /// <returns><c>True</c> if the member should be injected; otherwise <c>false</c>.</returns>
      public bool ShouldInject(MemberInfo member)
      {
       var info = member as PropertyInfo;

       if( member == null || info == null )
        return false;

       if (info.CanWrite)
        return _propertyInjectible.Contains(info.PropertyType);

       if( this.Settings == null )
        return false;

       var propList = member.GetCustomAttributes(this.Settings.InjectAttribute, true);

       return propList.Length > 0;
      }
}

When creating your kernel:

var heuristics = _kernel.Components.Get<ISelector>().InjectionHeuristics;
   heuristics.Add(new MyInjectionHeuristic());

Simple add additional types to the IList when you want to inject other types via properties.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文