bchavez / Bogus

:card_index: A simple fake data generator for C#, F#, and VB.NET. Based on and ported from the famed faker.js.
Other
8.51k stars 483 forks source link

How to make convert to generic method #542

Closed AhmedMagdu closed 2 months ago

AhmedMagdu commented 2 months ago

Bogus NuGet Package

35.5.0

.NET Version

.Net 7

Visual Studio Version

2022

What operating system are you using?

Windows

What locale are you using with Bogus?

en

What's the problem?

how to make this code generic or dynamic if have entityDto is customer how to make map properties of person in Faker customer have some properties and have List about customerAddresses how to make actually map with Address in Faker

public static async Task<List<CustomerInsertUpdateDto>> InsertFakeDataCustomer(int count, BaseService<Customer> service)
        {
            var fakeCustomers = new List<Customer>();
            // Create Faker instance to generate fake data
            var faker = new Faker<Customer>()
                .RuleFor(c => c.Name, f => f.Person.FirstName)
                .RuleFor(c => c.ForeignName, f => f.Person.LastName)
                .RuleFor(c => c.Email, f => f.Person.Email)
                .RuleFor(c => c.Phone, f => f.Phone.PhoneNumber());

            // Generate fake customer data
            for (int i = 0; i < count; i++)
            {
                fakeCustomers.Add(faker.Generate());
            }
            // Convert Customer objects to CustomerInsertUpdateDto objects
            var fakeCustomersDto = fakeCustomers.Select(c => new CustomerInsertUpdateDto
            {
                Name = c.Name,
                ForeignName = c.ForeignName,
                Email = c.Email,
                Phone = c.Phone,
                CustomerAddresses = GenerateFakeAddresses()
            }).ToList();

            // Assuming base is an instance of BaseService<CustomerInsertUpdateDto>
            return await service.InsertRangeAsync(fakeCustomersDto);
        }
        // Helper method to generate fake addresses
        private static List<CustomerAddressUpdateDto> GenerateFakeAddresses()
        {
            var faker = new Faker<CustomerAddressUpdateDto>()
                .RuleFor(a => a.Zone, f => f.Address.City())
                .RuleFor(a => a.Floor, f => f.Address.StreetName())
                .RuleFor(a => a.RegionName, f => f.Address.City())
                .RuleFor(a => a.Apartment, f => f.Address.BuildingNumber());

            // Generate a random number of fake addresses (between 1 and 5, for example)
            int numberOfAddresses = new Random().Next(1, 4); // Generate a random number between 1 and 5
            return faker.Generate(numberOfAddresses);
        }

Provide LINQPad Example

N/Y

What other possible solutions or alternatives have you considered?

N/Y

bchavez commented 2 months ago

Hi @AhmedMagdu , you'll need to be more specific with your questions:

how to make this code generic or dynamic if have entityDto is customer how to make map properties of person in Faker customer have some properties and have List about customerAddresses how to make actually map with Address in Faker

What do you mean "more generic or dynamic"? What problem are you trying to solve?

AhmedMagdu commented 2 months ago

İ mean how to make map between my entity to class on faker

Sent from Outlook for Androidhttps://aka.ms/AAb9ysg


From: Brian Chavez @.> Sent: Friday, April 19, 2024 1:29:14 AM To: bchavez/Bogus @.> Cc: AhmedMagdu @.>; Mention @.> Subject: Re: [bchavez/Bogus] How to make convert as generic or dynamic (Issue #542)

Hi @AhmedMagduhttps://github.com/AhmedMagdu , you'll need to be more specific with your questions:

how to make this code generic or dynamic if have entityDto is customer how to make map properties of person in Faker customer have some properties and have List about customerAddresses how to make actually map with Address in Faker

What do you mean "more generic or dynamic"? What problem are you trying to solve?

— Reply to this email directly, view it on GitHubhttps://github.com/bchavez/Bogus/issues/542#issuecomment-2065482995, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AI5O2E6RDUH7SX3FMPE2ZODY6BJMVAVCNFSM6AAAAABGM2PRP6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANRVGQ4DEOJZGU. You are receiving this because you were mentioned.Message ID: @.***>

bchavez commented 2 months ago

If you're talking about mapping entities to DTOs, then you'll need to use some kind of object mapping tool like ValueInjector, AutoMapper, Mapster, Mapperly, TinyMapper, or some other utility library to translate object values between classes.

Object translations or transformations into other objects is not a concern of Bogus. Here is a blog post that goes into different kinds of mapping tools and utility libraries:

Finally, here's a fixed up version using ValueInjecter:

private static List GenerateFakeAddresses() { var faker = new Faker() .RuleFor(a => a.Zone, f => f.Address.City()) .RuleFor(a => a.Floor, f => f.Address.StreetName()) .RuleFor(a => a.RegionName, f => f.Address.City()) .RuleFor(a => a.Apartment, f => f.Address.BuildingNumber());

int numberOfAddresses = new Random().Next(1, 4); return faker.Generate(numberOfAddresses); } public class Customer { public string Name { get; set; } public string ForeignName { get; set; } public string Email { get; set; } public string Phone { get; set;} } public class CustomerInsertUpdateDto { public string Name { get; set; } public string ForeignName { get; set; } public string Email { get; set; } public string Phone { get; set; } public List CustomerAddresses { get; set;} } public class CustomerAddressUpdateDto{ public string Zone { get; set; } public string Floor { get;set; } public string RegionName { get; set; } public string Apartment { get; set; } }


### OUTPUT
![image](https://github.com/bchavez/Bogus/assets/478118/340ac349-316c-4bc0-88de-ec931732b948)
bchavez commented 2 months ago

Also, consider just creating Faker<T>s for your DTOs without having to go to Entity -> DTO translation; eg:

Ultimately, you might not need new Faker<Customer>() if all you're doing is creating CustomerInsertUpdateDto in the first place; then just use new Faker<CustomerInsertUpdateDto>() instead of new Faker<Customer>().

AhmedMagdu commented 2 months ago

Yes I understand you look this code

public static List InsertFakeDataCustomer(int count) { var customerFaker = new Faker() .RuleFor(c => c.Name, f => f.Person.FirstName) .RuleFor(c => c.ForeignName, f => f.Person.LastName) .RuleFor(c => c.Email, f => f.Person.Email) .RuleFor(c => c.Phone, f => f.Phone.PhoneNumber());

var fakeCustomers = customerFaker.Generate(count);

var customerInsertDtos = fakeCustomers.Select(c => { var customerDto = Mapper.Map(c); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // here is the ValueInjecter mapping customerDto.CustomerAddresses = GenerateFakeAddresses(); return customerDto; }) .ToList();

return customerInsertDtos; }

private static List GenerateFakeAddresses() { var faker = new Faker() .RuleFor(a => a.Zone, f => f.Address.City()) .RuleFor(a => a.Floor, f => f.Address.StreetName()) .RuleFor(a => a.RegionName, f => f.Address.City()) .RuleFor(a => a.Apartment, f => f.Address.BuildingNumber());

int numberOfAddresses = new Random().Next(1, 4); return faker.Generate(numberOfAddresses); }

I mean how convert to generic for this code will receive any entity will make Faker data for exmaple if have the class is Customer will get class Person in Faker Or if have class Product will get class Commerce , etc .... by automatic How generate this logic


From: Brian Chavez @.> Sent: Friday, April 19, 2024 11:16 PM To: bchavez/Bogus @.> Cc: AhmedMagdu @.>; Mention @.> Subject: Re: [bchavez/Bogus] How to make convert as generic or dynamic (Issue #542)

Also, consider just creating Fakers for your DTOs without having to go to Entity -> DTO translation; eg:

Ultimately, you might not need new Faker() if all you're doing is creating CustomerInsertUpdateDto in the first place; then just use new Faker() instead of new Faker().

— Reply to this email directly, view it on GitHubhttps://github.com/bchavez/Bogus/issues/542#issuecomment-2067384917, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AI5O2E5BDOF2F3TTVFTRRH3Y6GQWRAVCNFSM6AAAAABGM2PRP6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANRXGM4DIOJRG4. You are receiving this because you were mentioned.Message ID: @.***>

bchavez commented 2 months ago

If you're looking for "Automatic" mapping between DTO/Entities to Datasets; you can try looking for:

AutoBogus:

Other than "Conventions", there is no way to automatically "generate" mappings between DTO/Entities and Datasets. A human must be involved in the process to map value generation to class entity/dto properties.


Tangentially, there is IDE tooling like Bogus.Tools.Analyzer that help "generate" .RuleFor() values, but they are default value rules, and you'll still need to specify what datasets are needed and assigned to entity/dto properties:

Bogus.Tools.Analyzer