避免必须在C#中提供基类参数

时间:2022-11-29 10:56:03

I've get a base class like so...

我得到了这样的基类......

public class BaseController : Controller
{
    private readonly IUserRepository userRepository;

    public BaseController(IUserRepository userRepository)
    {
        this.userRepository = userRepository;
    }
}

I want all of my MVC controllers to inherit from this class. Is there some way that I can avoid having to supply the 'userRepository' instance to the base class from every sub-classes constructor like this?

我希望我的所有MVC控制器都继承自这个类。有没有什么方法可以避免从这样的每个子类构造函数向基类提供'userRepository'实例?

public HomeController(IUserRepository repository) : base(repository)
{
}

Cheers, Ian.

5 个解决方案

#1


1  

I've you talk about not having to duplicate the constructor in the derived class, than the answer would be no. You could always provide a default constructor in the base class, which is using some sort of DI-container to get hold of an IUserRepository instance.

我是你在谈论不必在派生类中复制构造函数,而答案是否定的。您总是可以在基类中提供默认构造函数,它使用某种DI容器来获取IUserRepository实例。

If you safe some time typing, you can always provide a custom T4 template that includes the constructor for you. You can find an example here: http://www.hanselman.com/blog/ModifyingTheDefaultCodeGenerationscaffoldingTemplatesInASPNETMVC.aspx (although this mainly focuses on the view, the same goes for adding controllers).

如果您安全地键入一些时间,您可以随时提供包含构造函数的自定义T4模板。你可以在这里找到一个例子:http://www.hanselman.com/blog/ModifyingTheDefaultCodeGenerationscaffoldingTemplatesInASPNETMVC.aspx(尽管这主要集中在视图上,添加控制器也是如此)。

#2


0  

The only way I am aware of would be not to pass IUserRepository as a parameter of the base class and instead instantiating it in the base class using:

我所知道的唯一方法是不将IUserRepository作为基类的参数传递,而是使用以下方法在基类中实例化它:

protected readonly IUserRepository UserRepository = BindingFactory.GetInstance<IUserRepository>();

Where GetInstance<T>() calls the Resolve() method of the container. But this would depend on the type of IOC you are using.

其中GetInstance ()调用容器的Resolve()方法。但这取决于您使用的IOC类型。

#3


0  

You can use some wrapper class that inherites from BaseController and put some (what???) object to userRepository

您可以使用从BaseController继承的一些包装类,并将一些(what ???)对象放到userRepository中

public class WrapperController: BaseController
{
    public WrapperController()
    {
        base.userRepository = someObject;
    }
}

#4


0  

You can create a custom ControllerFactory and register it in global.asax

您可以创建自定义ControllerFactory并在global.asax中注册它

ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory())

The content of your CustomControllerFactory

CustomControllerFactory的内容

public class CustomControllerFactory : DefaultControllerFactory
{
    private readonly IUserRepository userRepository;

    public override IController CreateController(RequestContext requestContext, string controllerName)
    {
        return new BaseController(userRepository);
    }

}

This is also useful if you are using Dependency Injection.

如果您使用依赖注入,这也很有用。

More Information:

Simple Dependency Injection using a Custom MVC Controller Factory

使用自定义MVC控制器工厂进行简单的依赖注入

#5


0  

I think I've got it... when registering the contollers for the IoC Container, check whether they inherit from the base class and then if so add some property injection to the mapping. Voila!

我想我已经得到了...当为IoC容器注册控制器时,检查它们是否从基类继承,然后如果是这样,为映射添加一些属性注入。瞧!

I've since pondered though as to whether this is a bad design. Yes it saves some typing and makes things look simpler but its opening up some possibly significant side effects into a sub-classes operations. i.e. the sub-class is dependent on objects that haven't come via the constructor or via method parameters. They may or may not even be there.

我已经考虑过这是不是一个糟糕的设计。是的,它节省了一些打字并使事情看起来更简单,但它为子类操作开辟了一些可能很重要的副作用。即,子类依赖于未通过构造函数或通过方法参数来的对象。他们可能会或可能不会在那里。

#1


1  

I've you talk about not having to duplicate the constructor in the derived class, than the answer would be no. You could always provide a default constructor in the base class, which is using some sort of DI-container to get hold of an IUserRepository instance.

我是你在谈论不必在派生类中复制构造函数,而答案是否定的。您总是可以在基类中提供默认构造函数,它使用某种DI容器来获取IUserRepository实例。

If you safe some time typing, you can always provide a custom T4 template that includes the constructor for you. You can find an example here: http://www.hanselman.com/blog/ModifyingTheDefaultCodeGenerationscaffoldingTemplatesInASPNETMVC.aspx (although this mainly focuses on the view, the same goes for adding controllers).

如果您安全地键入一些时间,您可以随时提供包含构造函数的自定义T4模板。你可以在这里找到一个例子:http://www.hanselman.com/blog/ModifyingTheDefaultCodeGenerationscaffoldingTemplatesInASPNETMVC.aspx(尽管这主要集中在视图上,添加控制器也是如此)。

#2


0  

The only way I am aware of would be not to pass IUserRepository as a parameter of the base class and instead instantiating it in the base class using:

我所知道的唯一方法是不将IUserRepository作为基类的参数传递,而是使用以下方法在基类中实例化它:

protected readonly IUserRepository UserRepository = BindingFactory.GetInstance<IUserRepository>();

Where GetInstance<T>() calls the Resolve() method of the container. But this would depend on the type of IOC you are using.

其中GetInstance ()调用容器的Resolve()方法。但这取决于您使用的IOC类型。

#3


0  

You can use some wrapper class that inherites from BaseController and put some (what???) object to userRepository

您可以使用从BaseController继承的一些包装类,并将一些(what ???)对象放到userRepository中

public class WrapperController: BaseController
{
    public WrapperController()
    {
        base.userRepository = someObject;
    }
}

#4


0  

You can create a custom ControllerFactory and register it in global.asax

您可以创建自定义ControllerFactory并在global.asax中注册它

ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory())

The content of your CustomControllerFactory

CustomControllerFactory的内容

public class CustomControllerFactory : DefaultControllerFactory
{
    private readonly IUserRepository userRepository;

    public override IController CreateController(RequestContext requestContext, string controllerName)
    {
        return new BaseController(userRepository);
    }

}

This is also useful if you are using Dependency Injection.

如果您使用依赖注入,这也很有用。

More Information:

Simple Dependency Injection using a Custom MVC Controller Factory

使用自定义MVC控制器工厂进行简单的依赖注入

#5


0  

I think I've got it... when registering the contollers for the IoC Container, check whether they inherit from the base class and then if so add some property injection to the mapping. Voila!

我想我已经得到了...当为IoC容器注册控制器时,检查它们是否从基类继承,然后如果是这样,为映射添加一些属性注入。瞧!

I've since pondered though as to whether this is a bad design. Yes it saves some typing and makes things look simpler but its opening up some possibly significant side effects into a sub-classes operations. i.e. the sub-class is dependent on objects that haven't come via the constructor or via method parameters. They may or may not even be there.

我已经考虑过这是不是一个糟糕的设计。是的,它节省了一些打字并使事情看起来更简单,但它为子类操作开辟了一些可能很重要的副作用。即,子类依赖于未通过构造函数或通过方法参数来的对象。他们可能会或可能不会在那里。