【问题标题】:How to add service names to database如何将服务名称添加到数据库
【发布时间】:2021-07-04 11:28:08
【问题描述】:

我有界面

public interface ISocialService
    {
        //...
    }

和类

public class RedditService : ISocialService
{

        private readonly DbContext _context;

        public RedditService(DbContext context)
        {
            _context = context;
        }
}

我还有一些其他服务实现了 IRedditService。

这是我的 DbContext:

public class DbContext : IdentityDbContext
    {

        private readonly IEnumerable<ISocialService> _socialServices;
        public DbContext(DbContextOptions<CrastinatorContext> options, IEnumerable<ISocialService> socialServices) : base(options)
        {
            _socialServices = socialServices;
        }
        //...

        public DbSet<SiteName> SiteNames { get; set; }
        protected override void OnModelCreating(ModelBuilder builder)
        {
            //...
            foreach (var site in socialservices)
            {
                builder.Entity<SiteName>()
                    .HasData(new { Name = site.GetType().Name });

            }

        }

但我不能这样做,因为 SocialServices 已将 dbcontext 注入到构造函数中,因此我无法将 socialservices 注入到 dbcontext。 (循环依赖) 我要在db中添加方法名称的原因:

我想从特定服务向用户发送数据。 例如,如果用户有 RedditService 偏好然后从 RedditService 向他发送数据,如果用户有 ServiceA、ServiceB、 然后从 ServiceA 和 ServiceB 发送数据等等。

所以我想将这些服务名称存储在数据库中。 然后在控制器中我会检查用户首选项:如果(用户有 serviceA)然后从 serviceA 发送数据。

还有其他方法可以实现吗?

TLDR:我想将 MethodNames 添加到 SiteNames 表,但我不知道应该在哪里做。

【问题讨论】:

  • 你为什么要为不同的服务设置不同的表?而是有一个带有 FK 到 ServiceName 的服务表?
  • @Selvin 我想在 ServiceNames 表中有“ServiceA”和“ServiceB”。我的问题是:如何在应用启动时添加它?
  • 通过独立于 ServiceName 内部的内容添加它...动态表几乎总是糟糕的主意
  • @Selvin 我想出了这个想法,因为我想从特定服务向用户发送数据。例如,如果用户有 ServiceA 偏好,则从 ServiceA 向他发送数据,如果用户有 ServiceA、ServiceB,则从 ServiceA 和 ServiceB 发送数据等等。所以我想将这些服务名称存储在数据库中。然后在控制器中我会检查用户首选项:如果(用户有 serviceA)然后从 serviceA 发送数据。但为此,我需要将此服务名称存储在数据库中。
  • 正如我所写的那样,使用一个服务表并仅使用给定的 ServiceID 和 UserID 进行选择 ... ServiceID 应该是 ServiceNames 中的 ID 的 FK ... 不需要不同的表

标签: c# entity-framework asp.net-core dependency-injection


【解决方案1】:

您可以通过反射找到ISocialService 的所有实现,因此无需将它们注入DbContext。这是一个示例。

public interface ISocialService { }
public class FacebookService : ISocialService { }
public class RedditService : ISocialService { }

public class Program
{
    static void Main(string[] args)
    {
        var socialServices = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(s => s.GetTypes())
            .Where(p => typeof(ISocialService).IsAssignableFrom(p) && p.IsClass);

        foreach (var t in socialServices)
        {
            Console.WriteLine(t.Name);
        }
    }
}

不过,我建议稍微重新设计应用程序。否则,每次添加 ISocialService 的新实现或重命名任何现有的实现时,都需要重新为数据库设置种子。我会谨慎使用这种联轴器。

【讨论】:

  • Op 正在使用依赖注入;我不认为 DI 容器如何找到服务有问题,问题是循环依赖。
  • @IanMercer 是的,但他在 DbContext 中使用 DI 只是为了获取实现 ISocialService 的类型的名称。我建议通过反思来做到这一点,因此无需注入它们。我将更新我的答案以使其清楚,谢谢!
  • 感谢您的回答,您是否建议手动将可用服务添加到数据库?还是我解决这个问题的方法完全错误?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-21
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
相关资源
最近更新 更多