0

I want to make Email Activation in my project. I works with Entity Framework to database connections in repository layer and Services uses this layers.

I want create key and insert to database with Entity Framework and Dependency Injection service without noncontroller.

Repository 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);
}

Non Controller Class

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);
    }
}

in other class declares 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 }
};

in Startup:

public static IActivationService ActivationService;

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

I looked at this question and this one too, but I did not get any results.

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
OMANSAK
  • 1,066
  • 1
  • 12
  • 30

2 Answers2

1

As the other answers state you can just pass the class as a parameter to the non-controller class and the Dependency Injector will pass it for you.

public class EmailActivaitonKey
{
    private readonly IActivationService _activationService;

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

If you only want one instance of the service for the whole of the application then you add the service as a Singleton in ConfigureServices

services.AddSingleton<IActivationService, ActivationService>();

You don't need to create a static variable for the instance as the 'ServiceProvider' i.e. services object, will hold it for you.

EDIT You can pass the EmailActivationKey class as a parameter to another class and DI will inject it for you e.g.

public class EmailClass
{
    private readonly EmailActivationKey _key;

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

If you want a new one each time then change the services call back to scoped e.g.

services.AddScoped<EmailActivationKey>();

The DI will create a new one for you for each request.

Simply Ged
  • 8,250
  • 11
  • 32
  • 40
0

This is about the exact opposite of Dependency Injection (notice that you are not declaring the dependency, but effectively hiding it). This is known as the Service Locator anti-pattern:

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

If you want to use Dependency Injection, that should look like this (typo fixed):

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

Then, remove completely this and the ActivationService field:

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

Also, this is extremely weird:

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

I am not sure why you are expecting to find duplicate GUIDs, since that's exactly why they exist.

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120