是否可以使用Activator.CreateInstance()创建带有参数的构造函数的通用工厂?

时间:2012-01-24 20:42:40

标签: c# generics factory-pattern

当它返回的类需要构造函数中的参数时,有没有办法实现泛型工厂?我所有的工厂都是这样的:

public static class UserServiceFactory
{
    public static UserService GetService()
    {
        UserRepository userRepository = new UserRepository();
        return new UserService(userRepository);
    }

}

我试过这样的事情:

 public static TServiceClass GetService<TServiceClass>()
        where TServiceClass : class, new()
    {
        TServiceClass serviceClass = null;

        string repositoryName = typeof (TServiceClass).ToString().Replace("Service", "Repository");
        Type type = Type.GetType(repositoryName);

        if (type != null)
        {
            object repository = Activator.CreateInstance(type);
            serviceClass =  (TServiceClass)Activator.CreateInstance(typeof (TServiceClass), new[]{repository});
        }

        return serviceClass;
    }

然而,这当然不会起作用,因为我不能使用没有无参数构造函数的类作为泛型参数,但我觉得我很接近。我想过像GetService(Type serviceClassType)那样传递Service类,但是我不能声明方法的返回类型,并且在调用它时必须抛出它,我想避免它。

还有其他方法吗?这甚至可能吗?

1 个答案:

答案 0 :(得分:3)

您可以执行类似的操作,并将这两种类型作为类型参数:

public static TService GetService<TRepository, TService>() where TRepository:new()
{
    var repository = new TRepository();
    return (TService)Activator.CreateInstance(typeof(TService), repository);
}

或者,如果您希望依赖约定服务和存储库是相同的名称(仅用于说明):

public static TService GetService<TService>()
{
    var repositoryName = String.Concat(typeof(TService).Namespace, Type.Delimiter, typeof(TService).Name.Replace("Service", "Repository"));
    object repository = Activator.CreateInstance(Type.GetType(repositoryName));
    return (TService)Activator.CreateInstance(typeof(TService), repository);
}

这种感觉并不明显且不直观,也许还有更好,更强大的解决方案。

或许使用inversion of control container会更适合作为一种更好的方法。

使用容器,我只需解析UserService并让容器注入适当的存储库。如果UserService是来自其他东西的依赖项,那么让DI容器解析它,并且现代容器将解析依赖项的依赖项。