将数据库上下文提供给对象Factory

将数据库上下文提供给对象Factory

问题描述:

当我在代码(C#,但适用于我想的任何语言)中使用Factory模式时,我总是会问自己一个问题.

There is a question I always ask myself when I'm using a Factory pattern inside my code (C#, but it applies to any language I suppose).

我有一个服务",负责与数据库交互,处理对象以及与对象模型交互.

I have a "Service" that takes care of interacting with my database, do stuff with objects and interacts with my object model.

此服务有时使用Factory委托对象的实例化.但是该工厂显然需要自己与数据库进行交互才能正确地实例化我的对象.例如,将Database上下文传递给Create方法是好/坏做法吗?

This Service uses a Factory sometimes to delegate the instanciation of an object. But this factory obviously needs to interact by itself with the database to instanciate my object properly. Is it a good/bad practice to pass the Database context to the Create method for example?

像这样:

var myNewObject = MyFactory.Create(myDatabaseContext);

另一种方法是让服务"始终是唯一与数据库通信的人.

the other way would be to let the Service always be the only one to talk with the database.

var myNewObject = MyFactory.Create();
var extraProperty = myDatabaseContext.Get(something);
myNewObject.extraProp = extraProperty;

有什么建议吗?

将数据库上下文传递到工厂创建方法中的想法称为方法注入.这是依赖注入的一种形式,因此您处于正确的轨道上.

The idea of passing the database context into the factory create method is called method injection. This is a form of dependency injection, so you are on the right track.

您可以使用依赖项注入通过构造函数在工厂内部管理数据库上下文.工厂可能看起来像这样:

You can use dependency injection to manage your database context inside of your factory via the constructor. The factory could look something like this:

public class MyFactory 
{
    private readonly IMyDbContext dbContext;

    public MyFactory(IMyDbContext dbContext)
    {
        this.dbContext = dbContext;
    }

    public object Create()
    {
        // Use the dbContext, etc
    }
}

通常喜欢使用构造函数注入,因为它使方法签名的混乱程度降低了.我们也很可能将拥有一种类型的数据库上下文,因此将无需利用基于其他一些运行时信息的多态性.

Constructor injection is usually favored because it leaves method signatures less cluttered. We will also most likely have one type of database context so there will be no need to take advantage of polymorphism based on some other runtime information.

您可以选择使用像 Ninject 这样的依赖注入容器,或者使用我最喜欢的 SimpleInjector 为您管理依赖项.

You can choose to use a Dependency Injection Container like Ninject or, my favorite, SimpleInjector to manage the dependencies for you.

可以让DbContext仅由工厂使用.您可能需要注意的一件事是工厂的用户可能没有意识到工厂正在调用数据库.这可能是一件坏事,并且会对性能产生负面影响.通常,构造信息会传递到工厂方法中,而不是从数据库初始化到工厂方法中.您甚至可以更进一步,并使用存储库模式来如果您认为有必要并且还没有的话,可以抽象一些数据访问逻辑.

It is OK to have the DbContext only used by the factory. One thing you may want to watch out for is that a user of your factory may not realize that the factory is calling to the database. This could be a bad thing and have negative performance implications. Typically, construction information is passed into the factory method, not initialized into the factory method from the DB. You could even take it a step further and use the Repository Pattern to abstract away some more of the data access logic if you think it is necessary and you don't have that already.

要了解有关依赖注入的更多信息,如果您不熟悉,请

To learn more about Dependency Injection, in case you are unfamiliar, you can start here.

我理想的结构可能是这样的:

My ideal structure may look like this:

public class MyFactory : IFactory
{  
    public object Create(object someProperty)
    {
        // build object
    }
}

public class MyService
{
    private readonly IMyDbContext dbContext;
    private readonly IFactory factory;

    public MyService(IMyDbContext dbContext, IFactory factory)
    {
        this.dbContext = dbContext;
        this.factory = factory;
    }

    public void DoWork()
    {
        var property = dbContext.Get(something);
        var newObj = factory.Create(property);
        // Use stuff
    }
}