如何避免传递对容器的引用或对 EntityFactory 使用 CommonServiceLocator

发布于 2024-10-04 21:27:51 字数 1905 浏览 0 评论 0原文

我的实体类依赖于存储库。

public class User
{
    private readonly IUserRepository _userRepository;

    public User(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    ...
}

我有一个 EntityFactory 类,存储库使用它来创建实体。

public class UserRepository : IUserRepository
{
    private readonly EntityFactory _entityFactory;

    public UserRepository(EntityFactory entityFactory)
    {
        _entityFactory = entityFactory;
    }

    ...
}

// EntityFactory #1 with no references or dependencies to DI frameworks or CommonServiceLocator
public class EntityFactory
{
    public User InstantiateUser()
    {
        return new User(); // Requires IUserRepository parameter
    }
}

// EntityFactory #2 with reference to Ninject
using Ninject;

public class EntityFactory
{
    private readonly IKernel _kernel;

    public EntityFactory(IKernel kernel)
    {
        _kernel = kernel;
    }

    public User InstantiateUser(IKernel kernel)
    {
        return new User(_kernel.Get<IUserRepository>());
    }
}

// EntityFactory #3 with reference to CommonServiceLocator
using Microsoft.Practices.ServiceLocation;

public class EntityFactory
{
    public User InstantiateUser()
    {
        return new User(ServiceLocator.Current.GetInstance<IUserRepository>());
    }
}

有没有办法避免 EntityFactory 引用容器或使用 CommonServiceLocator? (与上下文无关)

或者我只是错误地设计了我的类,并且 User 类不应该依赖于任何存储库?

编辑:以下是使用 David 方法的代码:

// Ninject binding
Bind<Func<User>>().ToMethod(cxt => () => new User(cxt.Kernel.Get<IUserRepository>()));

// EntityFactory class
private readonly Func<User> _userFactory;
public EntityFactory(Func<User> userFactory)
{
    _userFactory = userFactory;
}
public User InstantiateUser()
{
    return userFactory.Invoke();
}

My Entity class has a dependency on a Repository.

public class User
{
    private readonly IUserRepository _userRepository;

    public User(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    ...
}

And I have an EntityFactory class used by the Repository to create entities.

public class UserRepository : IUserRepository
{
    private readonly EntityFactory _entityFactory;

    public UserRepository(EntityFactory entityFactory)
    {
        _entityFactory = entityFactory;
    }

    ...
}

// EntityFactory #1 with no references or dependencies to DI frameworks or CommonServiceLocator
public class EntityFactory
{
    public User InstantiateUser()
    {
        return new User(); // Requires IUserRepository parameter
    }
}

// EntityFactory #2 with reference to Ninject
using Ninject;

public class EntityFactory
{
    private readonly IKernel _kernel;

    public EntityFactory(IKernel kernel)
    {
        _kernel = kernel;
    }

    public User InstantiateUser(IKernel kernel)
    {
        return new User(_kernel.Get<IUserRepository>());
    }
}

// EntityFactory #3 with reference to CommonServiceLocator
using Microsoft.Practices.ServiceLocation;

public class EntityFactory
{
    public User InstantiateUser()
    {
        return new User(ServiceLocator.Current.GetInstance<IUserRepository>());
    }
}

Is there a way to avoid the EntityFactory having a reference to the container or using the CommonServiceLocator? (Context Agnostic)

Or am I just designing my classes wrong and the User class should not have a dependency on any Repositories?

Edit: Here is the code using the method from David:

// Ninject binding
Bind<Func<User>>().ToMethod(cxt => () => new User(cxt.Kernel.Get<IUserRepository>()));

// EntityFactory class
private readonly Func<User> _userFactory;
public EntityFactory(Func<User> userFactory)
{
    _userFactory = userFactory;
}
public User InstantiateUser()
{
    return userFactory.Invoke();
}

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

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

发布评论

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

评论(2

奶茶白久 2024-10-11 21:27:51

您的 DI 框架应该为您提供创建工厂的方法:

public class EntityFactory
{
    public EntityFactory(Func<User> userFactory) { /* ... */ }

    public User InstantiateUser()
    {
        return userFactory.Invoke();
    }
}

创建 EntityFactory 时,它将收到一个正确的 User 工厂,然后可以使用该工厂创建正确解析的用户没有任何参考国际奥委会的内容。

Your DI framework should provide you with a method of creating factories:

public class EntityFactory
{
    public EntityFactory(Func<User> userFactory) { /* ... */ }

    public User InstantiateUser()
    {
        return userFactory.Invoke();
    }
}

When the EntityFactory is created it'll receive a proper User factory which can then be used to create properly resolved users without any reference to the IoC.

彼岸花似海 2024-10-11 21:27:51

选项 2 或 3 有什么问题吗?如果您使用 IoC 或服务定位器,则需要在某处引用它。

我有一个对 IoC 容器的全局引用,并使用它来解析各处的接口。这看起来很像服务定位器,但使用的是 IoC 容器。

我不相信有办法解决这个问题。

What's wrong with option 2 or 3? If you are using IoC or a service locator, you will need to have a reference to it somewhere.

I have a global reference to the IoC container and use that to resolve the interfaces all over the place. This looks a lot like the service locator, but then instead using the IoC container.

I don't believe there is a way around this.

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