基类中的构造函数依赖注入

发布于 2024-11-10 01:00:44 字数 1873 浏览 4 评论 0原文

我正在使用实体框架构建一个存储库基类,所有实体存储库都将继承该基类。我想使用 Ninject 使用依赖注入将 DatabaseContext 注入基类中。我认为构造函数注入是正确的方法,但是在派生类中使用构造函数注入执行此操作,我必须将参数传递给基类中的构造函数,但我不希望这样做。那么,Setter Injection 更合适吗?

这是我的代码:

public abstract class BaseRepository<TEntity> : IDisposable 
    where TEntity : class
{
    private readonly DatabaseContext _databaseContext;

    protected BaseRepository(DatabaseContext databaseContext)
    {
        this._databaseContext = databaseContext;
    }
}

在上面的示例中使用构造函数注入,在我的派生类中,我必须将 databaseContext 对象传递给基类,我不喜欢对所有派生类执行此操作

public class UsuarioRepository : BaseRepository<IUsuario>,
    IUsuarioRepository
{
    public UsuarioRepository(DatabaseContext databaseContext)
        : base(databaseContext)
    {
    }
}

Setter 注入而不是构造函数注入是解决这个问题的好方法?最好的方法是什么?

更新:

使用 Setter 注入,我的派生类将没有构造函数:

public class UsuarioRepository : BaseRepository<IUsuario>, IUsuarioRepository
{
}

我的 Context 在所有应用程序中只有一个。我不需要派生类来传递上下文对象,但我喜欢将其注入基类中,以便将来使用模拟进行测试。

我解决了问题:

抱歉,我对这个问题感到困惑,但我正在解决构建工厂的问题:

public abstract class BaseRepository<TEntity> : IBaseRepository<TEntity>
   where TEntity : class
{
    private readonly ContextFactory _contextFactory = new ContextFactory();

    protected DatabaseContext CurrentContext
    {
        get
        {
            return this._contextFactory.GetCurrentContext();
        }
    }
 }

我的派生类将如下所示:

public class UsuarioRepository : BaseRepository<IUsuario>, IUsuarioRepository
{
}

而我的工厂将如下所示:

public class ContextFactory
{
    public DatabaseContext GetCurrentContext()
    {
        return new DatabaseContext();
    }
}

i'm building a repository base class with Entity Framework where all Entities repository will inherit. I want to inject the DatabaseContext in base class using Dependency Injection using Ninject. I think the Constructor Injection is the right way, but doing this with Constructor Injection in derived class I will must to pass parameter to constructor in base class and I don't want it. Therefore, a Setter Injection is more appropriate?

Here's my code:

public abstract class BaseRepository<TEntity> : IDisposable 
    where TEntity : class
{
    private readonly DatabaseContext _databaseContext;

    protected BaseRepository(DatabaseContext databaseContext)
    {
        this._databaseContext = databaseContext;
    }
}

Using Constructor Injection in the above example, in my derived class I will must to pass databaseContext object to base class, I don't like to doing this to all my derived class:

public class UsuarioRepository : BaseRepository<IUsuario>,
    IUsuarioRepository
{
    public UsuarioRepository(DatabaseContext databaseContext)
        : base(databaseContext)
    {
    }
}

Setter Injection instead of Constructor Injection is a good way to solve that? What is the best way?

Update:

Using Setter Injection my derived class's will not have constructors:

public class UsuarioRepository : BaseRepository<IUsuario>, IUsuarioRepository
{
}

My Context is only one in all application. I don't need derived class to pass context object, but i like to inject it in base class to using mocks for tests in future.

I Solve the problem:

Sorry, I'm confusing with the question, but i'm solving my problem building a Factory:

public abstract class BaseRepository<TEntity> : IBaseRepository<TEntity>
   where TEntity : class
{
    private readonly ContextFactory _contextFactory = new ContextFactory();

    protected DatabaseContext CurrentContext
    {
        get
        {
            return this._contextFactory.GetCurrentContext();
        }
    }
 }

And my derived class will look like that:

public class UsuarioRepository : BaseRepository<IUsuario>, IUsuarioRepository
{
}

And My Factory like that:

public class ContextFactory
{
    public DatabaseContext GetCurrentContext()
    {
        return new DatabaseContext();
    }
}

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

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

发布评论

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

评论(4

水染的天色ゝ 2024-11-17 01:00:44

属性注入意味着依赖项是可选的,而构造函数注入意味着依赖项是必需的。相应地选择一种模式。

在超过 95% 的情况下,构造函数注入是正确的模式。你不喜欢又怎样?

Property Injection implies that the dependency is optional, while Constructor Injection implies that the dependency is required. Choose a pattern accordingly.

In more than 95% of the cases Constructor Injection is the correct pattern. What about it don't you like?

初见终念 2024-11-17 01:00:44

我认为没有“最好的方法”。

构造函数和 setter 注入并不完全等同,因为 setter 注入为您提供了更多的灵活性。以下是我在两者之间进行选择的方法:

假设您创建了一个对象 A,而 A 需要一个 B 对象才能工作。要问的问题是:A 是否可以在没有与之关联的 B 的情况下存在/被实例化? A 对象没有 B 是有效状态吗?有时,A 拥有 null B 是没有意义的,那么构造函数注入是更好的解决方案。如果 B 可以稍后分配给 A,而不一定是在构造时,那么就使用 setter 注入。所有这些都取决于您尝试建模的领域,并且答案会因情况而异。

I don't think there is a "best way".

Constructor and setter injection are not exactly equivalent, as setter injection provides you a little more flexibility. Here is how I choose between the two:

Lets say you create an object A, and A needs a B object to work. Question to be asked is: Is it possible for A to exist/be instantiated without having a B associated with it? Is it a valid state for the A object to not have a B? Sometimes it does not make sense for A to ever have a null B, then constructor injection is the better solution. If, it is ok for B to be assigned to A later on and not necessarily at construction time, then go with setter injection. All this depends on the domain that you are trying to model, and the answers will change from situation to situation.

冷情妓 2024-11-17 01:00:44

真的,我看不出将参数传递给基类有任何问题。但如果这是绝对要求,您始终可以这样做:

public abstract class BaseRepository<TEntity> : IDisposable 
    where TEntity : class
{
    protected BaseRepository()
    {
    }

    protected abstract DatabaseContext GetContext();
}

现在您的派生类可以如下所示:

public class UsuarioRepository : BaseRepository<IUsuario>,
    IUsuarioRepository
{
    private DatabaseContext _databaseContext;

    public UsuarioRepository(DatabaseContext databaseContext)
    {
        _databaseContext = databaseContext;
    }

    protected override DatabaseContext GetContext()
    {
        return _databaseContext;
    }
}

现在您可以进行构造函数注入,而无需将参数传递给基本构造函数。但这确实是同一件事。

老实说,我不喜欢 setter 注入的想法,因为它看起来 DatabaseContext 是必需的依赖项。对于所需的依赖项,进行构造函数注入。如果它是可选的,那么无论如何,继续进行 setter 注入。
编辑

由于我们在评论中进行了长时间的对话,我对您想要完成的任务有了更好的理解。

如果您想将派生类与 DatabaseContext 解耦,最好以不同的方式进行设计。将派生类与其基类的依赖关系解耦是很困难的,如果您认为它们应该解耦,那么您将有更好的设计,根本不使用继承。

public class BaseRepository<TEntity> : IDisposable 
    where TEntity : class
{
    public BaseRepository(DatabaseContext context)
    {
    }
}

现在,您的派生类(将不再派生)将如下所示:

public class UsuarioRepository : IUsuarioRepository
{
    public UsuarioRepository(BaseRepository<IUsario> repository)
    {
    }

    // Implement other methods here
}

现在您可以拥有一个使用 DatabaseContext 的基类,并且您的派生类不再依赖于它。

Really, I can't see any problem with passing a parameter to a base class. But if that's an absolute requirement, you could always do this:

public abstract class BaseRepository<TEntity> : IDisposable 
    where TEntity : class
{
    protected BaseRepository()
    {
    }

    protected abstract DatabaseContext GetContext();
}

Now your derived classes can look like this:

public class UsuarioRepository : BaseRepository<IUsuario>,
    IUsuarioRepository
{
    private DatabaseContext _databaseContext;

    public UsuarioRepository(DatabaseContext databaseContext)
    {
        _databaseContext = databaseContext;
    }

    protected override DatabaseContext GetContext()
    {
        return _databaseContext;
    }
}

Now you can have constructor injection without passing a parameter to the base constructor. But it's really the same thing.

I honestly don't like the idea of setter injection, because it looks like the DatabaseContext is a required dependency. For required dependencies, do constructor injection. If it were optional, then by all means, go ahead and do setter injection.

EDIT:

Due to our long conversation in the comments, I have a much better understanding of what you're trying to accomplish.

If you want to decouple your derived classes from the DatabaseContext, you might be better off designing it differently. It is hard to decouple a derived class from its base class's dependencies, and if you think they should be decoupled, then you will have better design not using inheritance at all.

public class BaseRepository<TEntity> : IDisposable 
    where TEntity : class
{
    public BaseRepository(DatabaseContext context)
    {
    }
}

Now your derived classes (which would not be derived anymore) would look like this:

public class UsuarioRepository : IUsuarioRepository
{
    public UsuarioRepository(BaseRepository<IUsario> repository)
    {
    }

    // Implement other methods here
}

Now you can have your one base class that uses the DatabaseContext, and your derived classes are no longer dependent on it.

你与清晨阳光 2024-11-17 01:00:44

1. 构造函数、2. Setter 和 3. 接口注入这三种方式各有优缺点,具体使用哪种方式取决于具体情况。如果我处于你的位置,我会选择 setter,尽管界面也可能是一个不错的选择。

请求您仔细阅读这篇文章
http://www.devx.com/dotnet/Article/34066

All the three ways 1. Contstructor, 2. Setter and 3. Interface Injection has their advantages and disadvantages its depend on situation which one to use. If i would be in your place i would have gone with setter though interface can be a good choice also.

Request you to go through this article
http://www.devx.com/dotnet/Article/34066

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