1

我不太确定如何实现这一点,或者最好的策略是什么,基本上我有一个(MVC)控制器

public TestController(IService1 service1, IService2 service2,...)
{ }

(目前只有 2 个参数,但可以增加)。

我的想法是创建一个服务工厂类,因此我们可以为工厂提供一个参数,而不是为每个服务提供一个参数,然后获取我们需要的任何服务

private IService1 _service1;
public TestController(IServiceFactory serviceFactory)
{
    // this could also be called from a separate action, 
    // so we only get it when we need it
    _service1 = serviceFactory.Get<IService1>();
}

现在我的服务工厂实现有点垃圾,基本上我只有一个缓存所有注册服务和类型的字典:

/// <summary>
/// Service factory class
/// </summary>
/// <remarks>
/// Only one instance of this class should be created during the lifetime of the application
/// </remarks>
public class ServiceFactory : IServiceFactory
{
    /// <summary>
    /// Locking object
    /// </summary>
    private static readonly object _lock = new object();

    /// <summary>
    /// Collection of mappings
    /// </summary>
    private IDictionary<string, Func<IService>> _mappings;

    /// <summary>
    /// Default constructor
    /// </summary>
    public ServiceFactory()
    {
        _mappings = new Dictionary<string, Func<IService>>();
        registerMappings();
    }

    /// <summary>
    /// Get a service from the factory
    /// </summary>
    public T GetService<T>() where T : IService
    {
        if (_mappings.Count == 0)
            throw new InvalidOperationException("There are no mappings");

        lock (_lock)
        {
            var typeName = typeof(T).Name;
            if (_mappings.ContainsKey(typeName))
                return (T)_mappings[typeName]();

            return default(T);
        }
    }

    /// <summary>
    /// Register the mappings needed for this service factory
    /// </summary>
    private void registerMappings()
    {
        register<IService1>(() => new Service1())
             .register<IService2>(() => new Service2())
             .
             .
             .register<IServiceN>(() => new ServiceN());
    }

    /// <summary>
    /// Register the service classes
    /// </summary>
    private ServiceFactory register<T>(Func<IService> mapping) where T : IService
    {
        var type = typeof(T).Name;
        if (!_mappings.ContainsKey(type))
            _mappings.Add(type, mapping);

        return this;
    }
}

我的问题是,我可以在服务工厂中使用 IOC 容器并让它处理类型的注册和解析吗?这是一个好方法吗?

或者我可能有一个更根本的问题,我需要一个服务工厂,我应该使用一个吗?

我的 MVC 控制器需要重构只是一件简单的事情,即我可以尝试为每个服务坚持一个控制器?

只是想要一些关于这里最好的方法的提示,当涉及到 DI/工厂模式/其他模式等时,我仍然是一个新手 :)

非常感谢。

4

1 回答 1

1

我认为一般建议是您应该尝试遵守单一职责原则,在您的情况下,这可以解释为让您的控制器相对较小并专注于他们所做的事情。这样,服务依赖项的数量就会很少,并且传递所有必需的服务不应该是一件麻烦事。

也就是说,有时为多个服务提供单个访问点、减少传递的参数数量或允许服务本身之间的交互(IoC 容器不喜欢循环关系/依赖关系)可能很有用。

我需要后者,并决定创建一个 UnitOfWork 类,该类提供对所有服务槽属性的访问。UnitOfWork 将所有服务作为构造函数参数,然后作为构造函数参数传递给控制器​​。这允许通过 IoC 构建和注入整个链(服务、uow 和控制器),并且如果您保持对象构建成本较低(通过避免在构造函数中做大量工作),那么性能开销将最小化。

从务实的角度来看,这两种解决方案都可以。但是,使用第二种方法会使代码变得意大利面的风险更大,因为不清楚在哪里使用了哪些服务。

于 2013-04-10T19:07:31.407 回答