没有控制器的依赖注入

时间:2018-05-11 13:30:58

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

我想在我的项目中进行电子邮件激活。我使用Entity Framework来实现存储库层中的数据库连接,而Services使用这个层。

我想创建密钥并使用Entity Framework和Dependency Injection服务插入到数据库而不需要非控制器。

存储库Layes

public void Insert(T entity)
{
    if (entity == null)
    {
        throw new ArgumentNullException("entity");
    }

    _entities.Add(entity);
    SaveChanges();
}

ActivationService

public void Insert(EmailValid entity)
{
    _repositoryBase.Insert(entity);
}

非控制类

public class EmailActivaitonKey
{
    private readonly IActivationService _activationService;

    public EmailActivaitonKey()
    {
        this._activationService = Startup.ActivationService;
    }

    public string ActivationKey(string email)
    {
        string guid = Guid.NewGuid().ToString();
        while (_activationService.GetByFilter(i => i.ActivationKey == guid) != null)
        {
            guid = Guid.NewGuid().ToString();
        }

        string key = email + ":OSK:" + DateTime.Now + ":OSK:" + guid;
        EmailValid emailValid = new EmailValid
        {
            Email = email,
            Time = DateTime.Today,
            ActivationKey = key
        };

        _activationService.Insert(emailValid);
        return new Helpers.AESEncryption().EncryptText(key);
    }
}
其他类中的

声明EmailActivationKey

MailMessage mailMessage = new MailMessage
{
    From = new MailAddress("***@***.***"),
    Body = "Crypto Box Activation",
    Subject = $"<a href='/Email/Activation?key={new EmailActivaitonKey().ActivationKey(email)}'><h1>Click For Activation<h1><a>",
    To = { email }
};

在初创公司:

public static IActivationService ActivationService;

//then 
services.AddScoped<IActivationService, ActivationService>();
ActivationService = services.BuildServiceProvider().GetService<IActivationService>();

我查看了this questionthis one too,但我没有得到任何结果。

2 个答案:

答案 0 :(得分:1)

正如其他答案所述,您可以将该类作为参数传递给非控制器类,并且Dependency Injector将为您传递它。

public class EmailActivaitonKey
{
    private readonly IActivationService _activationService;

    public EmailActivaitonKey(IActivationService service)
    {
        this._activationService = service;
    }
    ....
}

如果您只需要整个应用程序的一个服务实例,那么您可以在ConfigureServices

中将服务添加为单身人士
services.AddSingleton<IActivationService, ActivationService>();

您不需要为实例创建静态变量,因为&#39; ServiceProvider&#39;即services对象,将为您保留。

修改 您可以将EmailActivationKey类作为参数传递给另一个类,DI会为您注入它。例如

public class EmailClass
{
    private readonly EmailActivationKey _key;

    public EmailClass(EmailActivationKey key)
    {
        _key = key;
    }
}

如果您每次都想要一个新的,那么将services回拨更改为范围,例如

services.AddScoped<EmailActivationKey>();

DI会为您的每个请求创建一个新的。

答案 1 :(得分:0)

这与依赖注入完全相反(请注意,您没有声明依赖关系,而是有效地隐藏它)。这称为服务定位器反模式:

public EmailActivaitonKey()
{
    this._activationService = Startup.ActivationService;
}

如果你想使用依赖注入,那应该是这样的(拼写错误):

public EmailActivationKey(IActivationService activationService)
{
    _activationService = activationService;
}

然后,完全删除此ActivationService字段:

ActivationService = services.BuildServiceProvider().GetService<IActivationService>();

另外,这非常奇怪:

string guid = Guid.NewGuid().ToString();
while (_activationService.GetByFilter(i => i.ActivationKey == guid) != null)
{
    guid = Guid.NewGuid().ToString();
}

我不确定为什么你期望找到重复的GUID,因为这就是它们存在的原因。