1

シリアル化についてたくさん読んだ後、DTOを作成することにしました。さらに読んだ後、AutoMapperを使用することにしました。

私がやりたいのは、親を変換し(十分に簡単)、初期化されている場合はエンティティプロパティを変換することです。これは、以下のようにValueResolverを使用して実行しました(完全に機能するようになったら、汎用にしようとする場合があります)。 。この部分は機能します。

public class OrderItemResolver : ValueResolver<Order, OrderItem>
{
    protected override OrderItem ResolveCore(Order source)
    {
        // could also use NHibernateUtil.IsInitialized(source.OrderItem)
        if (source.OrderItem is NHibernate.Proxy.INHibernateProxy)
            return null;
        else
            return source.OrderItem;
        }
    }
}

DTOをエンティティに戻すとき、初期化されていないエンティティについては、プロキシを作成して、エンティティがアクセスしたい場合にアクセスできるようにします。ただし、プロキシの作成方法がわかりません。必要に応じて、Castleを使用しています。

私は運が悪かったのでたくさんのことを試しました。以下のコードは、主に私が何をすべきかわからないままランダムに物事を試しているため、混乱しています。誰か提案がありますか?

public class OrderItemDTOResolver : ValueResolver<OrderDTO, OrderItem>
{
    protected override OrderItem ResolveCore(OrderDTO source)
    {
        if (source.OrderItem == null)
        {
            //OrderItem OrderItem = new ProxyGenerator().CreateClassProxy<OrderItem>(); // Castle.Core.Interceptor.

            //OrderItem OrderItem = new ProxyGenerator().CreateClassProxy<OrderItem>();
            //OrderItem.Id = source.OrderItemId;

            //OrderItem OrderItem = new OrderItem();
            //var proxy = new OrderItem() as INHibernateProxy;
            //var proxy = OrderItem as INHibernateProxy;
            //return (OrderItem)proxy.HibernateLazyInitializer
            //ILazyInitializer proxy = new LazyInitializer("OrderItem", OrderItem, source.OrderItemId, null, null, null, null);
            //return (OrderItem)proxy;
            //return (OrderItem)proxy.HibernateLazyInitializer.GetImplementation();

            //return OrderItem;

            IProxyTargetAccessor proxy = new Castle.Core.Interceptor.

            var initializer = new LazyInitializer("OrderItem", typeof(OrderItem), source.OrderItemId, null, null, null, null);
            //var proxyFactory = new SerializableProxyFactory{Interfaces = Interfaces, TargetSource = initializer, ProxyTargetType = IsClassProxy};

            //proxyFactory.AddAdvice(initializer);
            //object proxyInstance = proxyFactory.GetProxy();
            //return (INHibernateProxy) proxyInstance;
            return null;


            //OrderItem.Id = source.OrderItemId;
            //return OrderItem;
        }

        else
            return OrderItemDTO.Unmap(source.OrderItem);
    }
}

ありがとう、エリック

多分私はそれを複雑にしすぎた。これはうまくいくようです。誰かがそれに関する問題を見ますか?

public class OrderItemDTOResolver : ValueResolver<OrderDTO, OrderItem>
{
    protected override OrderItem ResolveCore(OrderDTO source)
    {
        if (source.OrderItem == null)
            return NHibernateSessionManager.Instance.Session.GetISession().Load<OrderItem>(source.AgencyId);

        else
            return OrderItemDTO.Unmap(source.OrderItem);
    }
}
4

1 に答える 1

1

これは、答えが「しない」、または少なくとも「おそらくすべきではない」というケースの 1 つかもしれません。DTO を NHibernate のマップされたオブジェクトに直接マップしている場合、実際にはマップされたオブジェクトをドメイン オブジェクトとして使用しているわけではなく、データベースにデータをプッシュしたりデータベースからデータをプッシュしたりするための凝った方法です。もちろん、これで十分かもしれませんが、過去に自分でこれを行ったことがありますが、同じ DTO データ形式を双方向で使用しようとすると問題があることがわかりました。クロスプロセスを行う場合は、サービスを (保守が難しい) CRUD レイヤーに変えています。同じプロセスにいる場合は、DTO で不要なデータ シャッフルを行っています。

DTO を送信することは問題ありませんが、クライアントが実際に必要としているものにより近い形式にデータを射影することを検討してください。返されるものは、実際のアクション (基本的にはコマンド オブジェクト) を実行するために必要なデータのみを表現する特定の DTO でより適切に表現されます。いくつかの自動プロパティを使用すると、簡単に構築できます。これにより、必要な情報のみを使用して必要なアクションを実行するビジネス メソッドを、実行するアクションに適した形式で作成できます。最近の私の主な AutoMapper (これは確かに) の用途は、着信 DTO をドメイン メソッドが使用できる型に変換することです。

また、マップされたオブジェクトのパブリック セッターは、検証なしでオブジェクトを任意のコードで操作できるため、望ましくありません。これは、それらを変更すると、それらが無効な状態になる可能性があることを意味します。

上記のことをあまり気にしない場合 (そして、常に適用できるとは限りません)、個々のインスタンスをロードする方法では、多くの個々のデータベースのロードを行ってしまう可能性があり、パフォーマンスの問題が発生する可能性があります。

于 2010-06-17T10:27:00.893 に答える