【问题标题】:How can I instantiate Services in MVC如何在 MVC 中实例化服务
【发布时间】:2017-07-05 14:20:25
【问题描述】:

我有一个使用洋葱架构的 ASP.Net MVC 5 项目,其中我有存储库和服务,并且我使用控制器中的服务。在我的控制器中,我需要使用我创建的IGenericService 变量,但是如何实例化这些变量?问题是我的 Service 的构造函数需要一个 IRepository,而 IRepository 也需要初始化。

我尝试的是 ConfigureServices(IServiceCollection services) 方法中的 AddSingleton(IGenericService<MyClass>, GenericService<MyClass>) Startup.cs 文件,但它似乎没有帮助。

编辑 正如我的@Nkosi 建议的那样,我正在尝试解决依赖关系并按照本教程进行操作:http://scottdorman.github.io/2016/03/17/integrating-asp.net-core-dependency-injection-in-mvc-4/。我现在的问题是我得到了一个invalid operation exception

尝试激活“WebExploitv2.Controllers.NavigationController”时无法解析“Repository.PrincipalServerContext”类型的服务

我的 startup.cs 现在看起来像这样:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var services = new ServiceCollection();
        ConfigureAuth(app);
        ConfigureServices(services);
        var resolver = new DefaultDependencyResolver(services.BuildServiceProvider());
        DependencyResolver.SetResolver(resolver);
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllerAsServices(typeof(Startup).Assembly.GetExportedTypes()
            .Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition)
            .Where(t => typeof(IController).IsAssignableFrom(t)
                || t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)));

        services.AddSingleton<IGenericRepository<Web_Documents>, GenericRepository<Web_Documents>>();
        services.AddSingleton<IGenericService<Web_Documents>, GenericService<Web_Documents>>();

        services.AddSingleton<IGenericRepository<Web_Categories>, GenericRepository<Web_Categories>>();
        services.AddSingleton<IGenericService<Web_Categories>, GenericService<Web_Categories>>();

        services.AddSingleton<IGenericService<Web_User_joint_Profils>, GenericService<Web_User_joint_Profils>>();
        services.AddSingleton<IGenericRepository<Web_User_joint_Profils>, GenericRepository<Web_User_joint_Profils>>();

        services.AddSingleton<IGenericRepository<Web_Group_joint_Profils>, GenericRepository<Web_Group_joint_Profils>>();
        services.AddSingleton<IGenericService<Web_Group_joint_Profils>, GenericService<Web_Group_joint_Profils>>();


        services.AddSingleton<IMenuService, MenuService>();
        services.AddSingleton<IMenuRepository, MenuRepository>();
    }
}

我还添加了一个DefaultDependencyResolver 类:

public class DefaultDependencyResolver : IDependencyResolver
{
    protected IServiceProvider serviceProvider;

    public DefaultDependencyResolver(IServiceProvider serviceProvider)
    {
        this.serviceProvider = serviceProvider;
    }

    public object GetService(Type serviceType)
    {
        return this.serviceProvider.GetService(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return this.serviceProvider.GetServices(serviceType);
    }
}

接下来我有 ServiceProviderExtension 类:

public static class ServiceProviderExtensions
{
    public static IServiceCollection AddControllerAsServices(this IServiceCollection services, IEnumerable<Type> controllerTypes)
    {
        foreach(var type in controllerTypes)
        {
            services.AddTransient(type);
        }
        return services;
    }
}

最后在我的控制器中,我有GenericService 的接口,它允许我访问Repository 并反过来访问我的数据库。我使用以下接口进行实例化

    private IGenericService<Web_User_joint_Profils> _userProfileService;
    private IGenericService<Web_Group_joint_Profils> _groupProfileService;
    private IGenericService<Web_Categories> _categoryService;
    PrincipalServerContext context;
    private NavigationController(PrincipalServerContext context, IGenericService<Web_User_joint_Profils> userProfileService, IGenericService<Web_Group_joint_Profils> groupProfileService, IGenericService<Web_Categories> categoryService)
    {
        _context = context;
        _userProfileService = userProfileService;
        _groupProfileService = groupProfileService;
        _categoryService = categoryService;
    }

请注意,My GenericService 将 POCO 用作泛型,以便知道在数据库中查找的位置。因此,对于Startup.ConfigureServices(IServiceCollection services) 中的每一个,我添加了一个AddSingleton 方法来向DI 容器注册这些服务和存储库。 任何想法为什么我会得到这个异常?

【问题讨论】:

标签: c# asp.net-mvc dependency-injection onion-architecture


【解决方案1】:

我不会在初创公司内部调用服务。

将您的IGenericService 实例化为私有只读,然后创建构造函数以调用startup.cs 或您决定使用它的任何地方。

private readonly IGenericService _genericService = new GenericService();
public IGenericService GenericService
{
    get{ return _genericService; }
    set{ _genericService = value; }
}

现在你将你的类称为:

GenericService.Method();

【讨论】:

    【解决方案2】:

    这很简单,使用在运行时传递给ConfigureServices 方法的IServiceCollection 实例:

    services.AddSingleton<IAbstraction, ConcreteImplementation>();
    

    或者,对于瞬态生命周期范围:

    services.AddTransient<IAbstraction, ConcreteImplementation>();
    

    或者,在你的情况下:

    services.AddSingleton<IGenericService<MyClass>, GenericService<MyClass>>();
    

    【讨论】:

    • 这不起作用我不知道为什么,这是我遇到的解决方案,但我不断收到 Null Reference Exception
    • @LéonardLaiter 你如何尝试注入依赖项?
    • 我相信这是我跳过的步骤:p 阅读@Nkosi 发布的文档,我会在到达那里时告诉你。
    • @LéonardLaiter 您应该进行构造函数注入或通过 IServiceProvider 实例解析您的服务。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    相关资源
    最近更新 更多