简体   繁体   中英

prevent object from instantiation in fluent builder pattern C#

i am trying to create fluent builder pattern to create user request as it has lot of parameters. for simplicity i am just showing few parameters

Here is my request class or the model

public class Request
    {
        public string UserName {  get; set; }

        public string Password {  get; set; }

        public string Token {  get; set; }


    }

Here is my builder class that build the requests.

 public class RequestBuilder
    {
        private string _username;
        private string _password;
        private string _token;

        public RequestBuilder UserName(string username)
        {
            _username = username;
            return this;

        }

        public RequestBuilder Password(string password)
        {
            _password = password;
            return this;

        }

        public RequestBuilder Token(string token)
        {
            _token = token;
            return this;

        }

        public static implicit operator Request(RequestBuilder requestBuilder)
        {

            return new Request()
            {

                UserName = requestBuilder._username,
                Password = requestBuilder._password,
                Token = requestBuilder._token

            };
        }
    }

At a glance this approach might look working but it has security holes like

  1. User can create Request direct using Request request = new Request()
  2. if i restric the request class by implementing the parameterized constructor in Request class

      public Request(RequestBuilder rb){ UserName = rb._username; Password = rb._password; Token = rb._token; } 

In this case i need to create set and get method in RequestBuilder which will eventually expose RequestBuilder as follows

RequestBuilder rb = new RequestBuilder();
rb._username ="test";

so can anyone tell me how shall i protect Request class preventing from instantiation.

I tried to find the solution and end up with the following

  1. using Builder as nested class
  2. making Request class default constructor private. However, Builder is a nested class it can access request class and instantiate it
  3. In order to create the object of Request class user has to go through the Builder only.

Request request = new Request.Builder().UserName("user").Password("abc").Build();

Sample code

public class Request
    {
        public string UserName {   get; private set; }

        public string Password {  get; private set; }

        public string Token { get; private set; }


        private Request(){




        }

        public class Builder
        {

            private Request request = new Request();

            public Builder UserName(string username)
            {
                request.UserName = username;
                return this;

            }

            public Builder Password(string password)
            {
                request.Password = password;
                return this;

            }

            public Builder Token(string token)
            {
                request.Token = token;
                return this;

            }


            public Request Build()
            {

                return request;
            }


        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM