如何为嵌套对象创建生成器
How to created builder for nested objects
我正在寻找一种方法来创建可以创建嵌套对象的构建器。
我已经读过这个主题:
但这种方法是 modyfing model/entities,我想避免。
我有几个型号:
广告有一个所有者,所有者有一个地址和地址 有一个 联系人 实体。
public class Advertisment
{
public string AdvertismentId { get; set; }
public Owner Owner { get; set; }
}
public class Owner
{
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public Contact Contact { get; set; }
}
public class Contact
{
public string PhoneNo { get; set; }
}
我想链接这样的方法(或类似的方法):
var ad = new AdBuilder()
.WithId("123")
.WithOwner(x =>
x.WithName("NameOfOwner")
x.WithAddress(x => x.WithStreet("SomeStreet"))
.WithContact(y => y.WithPhoneNo("123-345-789"))));
我在这里准备了代码:
https://rextester.com/TRN19779
我不想修改模型,因为它们是从 JSON 架构生成的,我将它们保存在单独的 class 库中。我将使用上面的构建器将一个对象映射到另一个对象。
我正在准备一个对象发送给第 3 方消费者。
有人会这么友善并提供一点帮助吗?
这可以使用接口来完成。每个子 object
都有一个 interface
用于构造它。例如,Owner
class 具有相应的 IOwner
接口,允许用户填充 Owner
class
.
的属性
public interface IBuild
{
Advertisement Build( );
}
public interface IAdvertisement : IBuild
{
IAdvertisement WithID( string id );
IAdvertisement WithOwner( Action<IOwner> func );
}
public interface IOwner
{
IOwner WithName( string name );
IOwner WithAddress( Action<IAddress> func );
}
public interface IAddress
{
IAddress WithStreet( string street );
IAddress WithContact( Action<IContact> func );
}
public interface IContact
{
IContact WithPhoneNumber( string phoneNumber );
}
public class AdvertisementBuilder : IAdvertisement, IOwner, IAddress, IContact
{
private readonly Advertisement _advert = new( )
{ Owner = new( ) { Address = new( ) { Contact = new( ) } } };
private AdvertisementBuilder( )
{ }
public static IAdvertisement Create( ) =>
new AdvertisementBuilder( );
public IOwner WithAddress( Action<IAddress> func )
{
func( this );
return this;
}
public IAddress WithContact( Action<IContact> func )
{
func( this );
return this;
}
public IAdvertisement WithID( string id )
{
_advert.AdvertisementId = id;
return this;
}
public IOwner WithName( string name )
{
_advert.Owner.Name = name;
return this;
}
public IAdvertisement WithOwner( Action<IOwner> func )
{
func( this );
return this;
}
public IContact WithPhoneNumber( string phoneNumber )
{
_advert.Owner.Address.Contact.PhoneNo = phoneNumber;
return this;
}
public IAddress WithStreet( string street )
{
_advert.Owner.Address.Street = street;
return this;
}
// Here you can do some validation and make sure
// any required information has been filled in.
public Advertisement Build( ) => _advert;
}
static void Main( string[ ] _ )
{
var advertisement = AdvertisementBuilder.Create( )
.WithID( "Some id" )
.WithOwner( o => o.WithName( "Bill" )
.WithAddress( a => a.WithStreet( "Some street" )
.WithContact( c => c.WithPhoneNumber( "905-334-5839" ) ) ) )
.Build( );
}
我正在寻找一种方法来创建可以创建嵌套对象的构建器。
我已经读过这个主题:
我有几个型号: 广告有一个所有者,所有者有一个地址和地址 有一个 联系人 实体。
public class Advertisment
{
public string AdvertismentId { get; set; }
public Owner Owner { get; set; }
}
public class Owner
{
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public Contact Contact { get; set; }
}
public class Contact
{
public string PhoneNo { get; set; }
}
我想链接这样的方法(或类似的方法):
var ad = new AdBuilder()
.WithId("123")
.WithOwner(x =>
x.WithName("NameOfOwner")
x.WithAddress(x => x.WithStreet("SomeStreet"))
.WithContact(y => y.WithPhoneNo("123-345-789"))));
我在这里准备了代码: https://rextester.com/TRN19779
我不想修改模型,因为它们是从 JSON 架构生成的,我将它们保存在单独的 class 库中。我将使用上面的构建器将一个对象映射到另一个对象。 我正在准备一个对象发送给第 3 方消费者。
有人会这么友善并提供一点帮助吗?
这可以使用接口来完成。每个子 object
都有一个 interface
用于构造它。例如,Owner
class 具有相应的 IOwner
接口,允许用户填充 Owner
class
.
public interface IBuild
{
Advertisement Build( );
}
public interface IAdvertisement : IBuild
{
IAdvertisement WithID( string id );
IAdvertisement WithOwner( Action<IOwner> func );
}
public interface IOwner
{
IOwner WithName( string name );
IOwner WithAddress( Action<IAddress> func );
}
public interface IAddress
{
IAddress WithStreet( string street );
IAddress WithContact( Action<IContact> func );
}
public interface IContact
{
IContact WithPhoneNumber( string phoneNumber );
}
public class AdvertisementBuilder : IAdvertisement, IOwner, IAddress, IContact
{
private readonly Advertisement _advert = new( )
{ Owner = new( ) { Address = new( ) { Contact = new( ) } } };
private AdvertisementBuilder( )
{ }
public static IAdvertisement Create( ) =>
new AdvertisementBuilder( );
public IOwner WithAddress( Action<IAddress> func )
{
func( this );
return this;
}
public IAddress WithContact( Action<IContact> func )
{
func( this );
return this;
}
public IAdvertisement WithID( string id )
{
_advert.AdvertisementId = id;
return this;
}
public IOwner WithName( string name )
{
_advert.Owner.Name = name;
return this;
}
public IAdvertisement WithOwner( Action<IOwner> func )
{
func( this );
return this;
}
public IContact WithPhoneNumber( string phoneNumber )
{
_advert.Owner.Address.Contact.PhoneNo = phoneNumber;
return this;
}
public IAddress WithStreet( string street )
{
_advert.Owner.Address.Street = street;
return this;
}
// Here you can do some validation and make sure
// any required information has been filled in.
public Advertisement Build( ) => _advert;
}
static void Main( string[ ] _ )
{
var advertisement = AdvertisementBuilder.Create( )
.WithID( "Some id" )
.WithOwner( o => o.WithName( "Bill" )
.WithAddress( a => a.WithStreet( "Some street" )
.WithContact( c => c.WithPhoneNumber( "905-334-5839" ) ) ) )
.Build( );
}