简体   繁体   English

通用实现,但构造函数参数取决于具体类

[英]Generic implementation, but constructor arguments depend on concrete class

In a generic class I have to create a new object of the same type: 在通用类中,我必须创建一个相同类型的新对象:

public abstract class ViewModel<TPrimaryModel>
{
    public void DoSomething()
    {
        ...
        ViewModel<TPrimaryModel> newViewModel = new TPrimaryModel(someArguments);
    }
}

Doing this isn't supported by C#. C#不支持这样做。 So I decided to introduce a CreateInstance -method: 因此,我决定引入CreateInstance方法:

public abstract class ViewModel<TPrimaryModel>
{
    public void DoSomething()
    {
        ...
        ViewModel<TPrimaryModel> newViewModel = CreateInstance(someArguments);
    }

    protected abstract ViewModel<TPrimaryModel> CreateInstance(Object someArguments);
}

public class UserViewModel : ViewModel<User>
{
    public UserViewModel(Object someArguments)
    {
        ...
    }

    protected override ViewModel<TPrimaryModel> CreateInstance(Object someArguments)
    {
        return new UserViewModel(someArguments);        
    }
}

The parameters which have to be passed (some Service -classes) are class variables. 必须传递的参数(某些Service类)是类变量。 Unfortunately some ViewModel s need some more services then others. 不幸的是,某些ViewModel需要比其他服务更多的服务。 Example: ViewModelA viewModelA = new ViewModelA(serviceA, 5, "ViewModelA"); 示例: ViewModelA viewModelA = new ViewModelA(serviceA, 5, "ViewModelA"); ViewModelB viewModelB = new ViewModelB(serviceB, serviceA, 6, "ViewModelB");

I wonder what's the right way to go. 我想知道正确的方法是什么。 Encapsulate the arguments for object creation? 封装用于创建对象的参数? Factory pattern? 工厂模式? Or should I avoid inheritance in that situation and stick to composition? 还是应该避免在那种情况下继承并坚持合成?

I could also always pass "all" services. 我也可以始终通过“所有”服务。 Or provide a class which provides access to all services. 或提供可以访问所有服务的类。 But I guess those are bad ideas. 但是我想那是个坏主意。

I don't know all too much about the rest of your architecture, but these would be my considerations: 我对您的体系结构的其余部分不太了解,但这是我的考虑因素:

If I already use DI: Most container support per service/type bootstrapping configuration. 如果我已经使用DI:每个服务/类型引导配置的大多数容器支持。 As long as you're not starting to do dynamic stuff during composition it should remain fairly comprehensive 只要您在撰写过程中不开始做动态工作,就应该保持相当全面

Else: pass a Func<ViwModel<T>> factory method (as constructor parameter to your base class). 否则:传递Func<ViwModel<T>>工厂方法(作为基类的构造函数参数)。 It's probably the easiest and cleanest way to do what you want. 这可能是您要做的最简单,最干净的方法。

As you pointed out passing all services (would be an unmaintainable mess rather quickly) isn't a good idea. 正如您指出的那样,传递所有服务(很快就会造成无法维护的混乱)并不是一个好主意。 When it comes to the service locator pattern (quoting you "Or provide a class which provides access to all services"), this is a very opinionated discussion, with some very good insight over there: Is ServiceLocator an anti-pattern? 关于服务定位器模式(引用您“或提供一个提供对所有服务的访问权限的类”),这是一个非常有思想的讨论,在那边有一些很好的见解: ServiceLocator是反模式吗? If you ask me; 如果你问我; there are more places where it's harming than the other way round. 反之,危害更大的地方更多。 But hey, it's your software. 但是,这是您的软件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM