Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Lazy property

Tags:

c#-4.0

I have a Lazy property in my class:

private Lazy<ISmtpClient> SmtpClient
    {
        get
        {
            return new Lazy<ISmtpClient>(() => _objectCreator.Create<ISmtpClient>(), true);
        }
    }

Also a methode that uses this proptery:

public void SendEmail(MailMessage message)
    {
        SmtpClient.Value.ServerName = "testServer";
        SmtpClient.Value.Port = 25;

        SmtpClient.Value.Send(message);
    }

But in my SmtpClient, in Send(string message) methode are all the propteries that i initialized in the above SendEmail(MailMessage message) methode, null.

How can i fix this?

Thanks in advance.

like image 522
Djave Avatar asked Feb 06 '13 13:02

Djave


2 Answers

You are using Lazy<T> wrong.

When using Lazy<T> you expose a property of the actual type and you have one Lazy<T> instance. You don't create a new one every time the property is accessed:

Lazy<ISmtpClient> _smtpClient =
    new Lazy<ISmtpClient>(() => _objectCreator.Create<MySmtpClient>(), true);

private ISmtpClient SmtpClient
{
    get
    {
        return _smtpClient.Value;
    }
}

Now, the first time the SmtpClient property is accessed, the object creator creates a new instance of MySmtpClient. This is returned. On subsequent calls, the same instance is returned.

The usage would be like this:

public void SendEmail(MailMessage message)
{
    SmtpClient.ServerName = "testServer";
    SmtpClient.Port = 25;

    SmtpClient.Send(message);
}
like image 172
Daniel Hilgarth Avatar answered Sep 26 '22 06:09

Daniel Hilgarth


Daniel's answer is correct. Just want to add a clarification on why your code doesn't work.

Every time you access SmtpClient, in your original code, a new Lazy<ISmtpClient> object is created, which is then initialized immediately with SmtpClient.Value. This gives you a new ISmtpClient object on each line.

You need to construct the Lazy<T> object just once, and return that in the Property's getter, as in Daniels code. The property's type should be the type you want to use (i.e. you don't expose a Lazy<T> type to the consumer).

like image 43
wensveen Avatar answered Sep 22 '22 06:09

wensveen