Code Monkey home page Code Monkey logo

ease's Introduction

Illustration of Thulani being himself

Open Docs ๐Ÿ‘‹

Iโ€™m an software developer, husband, dad and tea lover. I currently work as a Senior Software Engineer in The Netherlands ๐ŸŒท.

  • ๐Ÿ“ฑ Iโ€™m currently working a lot in Python and .NET Core with Docker and K8s.
  • ๐Ÿค“ Iโ€™m currently learning F# and it may just lead to Haskell.
  • ๐Ÿ’š I enjoy home automation. I use Zigbee devices, Home Assistant, Conbee II and Node Red.
  • ๐Ÿ’ฌ Ask me about Functional Programming, Python and.NET Core.
  • ๐Ÿ“ซ How to reach me: Instagram
  • ๐Ÿšด๐Ÿฝโ€โ™€๏ธ Fun fact: I love taking photographs of pretty much anything but mainly I do nature and archticture!

ease's People

Contributors

chivandikwa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

ease's Issues

How to set properties after construction with private set?

Hi,

Do you have an idea on how to set properties with a private set after construction?

For simplicity I've created a Customer object.

public class Customer
{
    public int Id { get; init; }

    public string Name { get; init; }

    public string Email { get; private set; }

    public int Age { get; private set; }

    public Customer(int id, string name)
    {
        Id = id;
        Name = name ?? throw new ArgumentNullException(nameof(name));
    }

    public void SetEmail(string email)
    {
        if (string.IsNullOrWhiteSpace(email))
        {
            throw new ArgumentException($"'{nameof(email)}' cannot be null or whitespace.", nameof(email));
        }

        Email = email;
    }

    public void SetAge(int age)
    {
        if (age < 18)
        {
            throw new ArgumentException(nameof(age));
        }

        Age = age;
    }
}

The Builder. Unable to set the Age property

internal class CustomerBuilder : Builder<Customer>
{
    private readonly Faker _faker = new();

    protected override Customer CreateInstance()
    {
        var customer = new Customer(Get(x => x.Id), Get(x => x.Name));
        return customer;
    }

    public override Builder<Customer> ThatIsValid()
    {
        With(x => x.Id, 5);
        With(x => x.Name, _faker.Person.FullName);
        With(x => x.Age, 23); // This doesn't work...

        return this;
    }
}

What does work is the following:

internal class CustomerBuilder : Builder<Customer>
{
    private readonly Faker _faker = new();

    protected override Customer CreateInstance()
    {
        var customer = new Customer(Get(x => x.Id), Get(x => x.Name));

        customer.SetAge(Get(x => x.Age));
        // if I have more properties I can fill them with other methods here

        return customer;
    }

    public override Builder<Customer> ThatIsValid()
    {
        With(x => x.Id, 5);
        With(x => x.Name, _faker.Person.FullName);
        With(x => x.Age, 23); // You must also set it of course

        return this;
    }
}

But let's say I have strange business logic. For example the SetEmail can only be called when Age is 0. So actually not being set yet. I could add all those Setxxxx methods in the CreatInstance method but then they always get values. Then I have to overwrite the ThatIsValid values with in example Age is 0 again. Not really ideal...

I know it is strange but think of a registration process. I have a Status property and I need to set some properties only when the status is a particular value. It is not possible now.

Possible solution
I think the solution is to introduce a Has method in the builder so you can do this:

internal class CustomerBuilder : Builder<Customer>
{
    private readonly Faker _faker = new();

    protected override Customer CreateInstance()
    {
        var customer = new Customer(Get(x => x.Id), Get(x => x.Name));

        if (Has(x => x.Age))
        {
            customer.SetAge(Get(x => x.Age));
        }

        if (Has(x => x.Email))
        {
            customer.SetEmail(Get(x => x.Email));
        }

        return customer;
    }

    public Builder<Customer> ThatIsValidWithAgeNotSet()
    {
        With(x => x.Id, 5);
        With(x => x.Name, _faker.Person.FullName);

        return this;
    }

    public override Builder<Customer> ThatIsValid()
    {
        With(x => x.Id, 5);
        With(x => x.Name, _faker.Person.FullName);
        With(x => x.Age, 23);
        With(x => x.Email, _faker.Person.Email);

        return this;
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.