结构图构造函数重载

发布于 2024-11-27 23:56:15 字数 1535 浏览 2 评论 0原文

我有一个命令类需要有 2 个构造函数。然而, 使用结构图似乎我只能指定一个构造函数 被使用。我现在已经通过对具体的子类型解决了这个问题 命令类,每个实现都有自己的实现 接口和构造函数。就像下面的代码所示。这 ISelectCommand 实现了两个单独的接口 string 构造函数和 int 构造函数,只是为了 使用结构图注册两个子类型。

然而,我认为这是一个黑客行为,我只是想知道为什么它不是 结构图可以通过以下方式解析构造函数签名 作为构造函数参数传入的类型?然后我就可以注册了 SelectProductCommand 作为 ISelectCommand 和 像这样实例化它: ObjectFactury.With(10).Use>(); orObjectFactury.With("testproduct").Use>();

public class SelectProductCommand : ISelectCommand<IProduct>,
ICommand, IExecutable
{
   private readonly Func<Product, Boolean> _selector;
   private IEnumerable<IProduct> _resultList;

   public SelectProductCommand(Func<Product, Boolean> selector)
   {
       _selector = selector;
   }

   public IEnumerable<IProduct> Result
   {
       get { return _resultList; }
   }

   public void Execute(GenFormDataContext context)
   {
       _resultList = GetProductRepository().Fetch(context,
_selector);
   }

   private Repository<IProduct, Product> GetProductRepository()
   {
       return ObjectFactory.GetInstance<Repository<IProduct,
Product>>();
   }
}

public class SelectProductIntCommand: SelectProductCommand
{
    public SelectProductIntCommand(Int32 id): base(x =>
 x.ProductId == id) {}
}

public class SelectProductStringCommand: SelectProductCommand
{
    public SelectProductStringCommand(String name): base(x =>
x.ProductName.Contains(name)) {}
}

PS我知道如何告诉StructureMap使用什么构造函数映射,但我的问题是是否有一种方法可以让Structuremap根据传递给构造函数的参数选择正确的构造函数(即使用常规方法重载)。

I have a command class that needs to have 2 constructors. However,
using structuremap it seems that I can only specify one constructor to
be used. I have solved the problem for now by subtyping the specific
command class, which each implementation implementing it's own
interface and constructor. Like the code below shows. The
ISelectCommand implements two separate interfaces for the
string constructor and the int constructor, just for the sake of
registering the two subtypes using structuremap.

However, I consider this a hack and I just wonder why is it not
possible for structuremap to resolve the constructor signature by the
type passed in as parameter for the constructor? Then I could register
the SelectProductCommand as an ISelectCommand and
instantiate it like:
ObjectFactury.With(10).Use>();
orObjectFactury.With("testproduct").Use>();

public class SelectProductCommand : ISelectCommand<IProduct>,
ICommand, IExecutable
{
   private readonly Func<Product, Boolean> _selector;
   private IEnumerable<IProduct> _resultList;

   public SelectProductCommand(Func<Product, Boolean> selector)
   {
       _selector = selector;
   }

   public IEnumerable<IProduct> Result
   {
       get { return _resultList; }
   }

   public void Execute(GenFormDataContext context)
   {
       _resultList = GetProductRepository().Fetch(context,
_selector);
   }

   private Repository<IProduct, Product> GetProductRepository()
   {
       return ObjectFactory.GetInstance<Repository<IProduct,
Product>>();
   }
}

public class SelectProductIntCommand: SelectProductCommand
{
    public SelectProductIntCommand(Int32 id): base(x =>
 x.ProductId == id) {}
}

public class SelectProductStringCommand: SelectProductCommand
{
    public SelectProductStringCommand(String name): base(x =>
x.ProductName.Contains(name)) {}
}

P.s. I know how to tell structuremap what constructor map to use, but my again my question is if there is a way to have structuremap select the right constructor based on the parameter passed to the constructor (i.e. using regular method overloading).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

惟欲睡 2024-12-04 23:56:15

简短的答案是 这篇文章由 Structuremap 的创建者创建。

长答案是关于您在那段代码中的结构。在我看来,命令根据定义是一个对“实体”执行某些操作的“类”,即它以某种方式修改该类。想想创建新产品命令。

如果我没记错的话,这里您正在使用命令进行查询。这里还存在一些关注点分离的问题。发布的命令定义了要做什么以及如何做,这太多了,并且您获得了正在使用的那种服务位置

private Repository<IProduct, Product> GetProductRepository()
{
    return ObjectFactory.GetInstance<Repository<IProduct, Product>>();
}

我构造命令的方式是使用 CreateProductCommand 作为数据契约,即它只包含产品信息等数据。
然后,您有一个 CreateProductCommandHandler,它使用单个方法 HandleExecute 实现 IHandles。这样你就可以更好地分离关注点和可测试性。

至于查询部分,只需直接在控制器/演示器中使用存储库,或者使用 查询对象模式

The short answer is this post by the creator of Structuremap.

The long answer is regarding the structure you have in that piece of code. In my view, a command is by definition a "class" that does something to an "entity", i.e it modifies the class somehow. Think CreateNewProductCommand.

Here you are using commands for querying, if I'm not mistaken. You also have a bit of a separation of concern issue floating around here. The command posted defines what to do and how to do it, which is to much and you get that kind of Service location you're using in

private Repository<IProduct, Product> GetProductRepository()
{
    return ObjectFactory.GetInstance<Repository<IProduct, Product>>();
}

The way I'd structure commands is to use CreateProductCommand as a data contract, i.e it only contains data such as product information.
Then you have a CreateProductCommandHandler which implements IHandles<CreateProductCommand> with a single method Handle or Execute. That way you get better separation of concern and testability.

As for the querying part, just use your repositores directly in your controller/presenter, alternatively use the Query Object pattern

甜妞爱困 2024-12-04 23:56:15

我想我使用一个小的实用程序类解决了这个问题。该类从 ObjectFactory 获取具体类型,并根据传入工厂方法的参数使用该类型来构造实例。现在,在“客户端”端,我使用 ObjectFactory 创建 CommandFactory 的实例。 CommandFactory 的实现是在另一个解决方案中,因此“客户端解决方案”仍然独立于“服务器”解决方案。

public class CommandFactory
{

    public ICommand Create<T>()
    {
        return Create<T>(new object[] {});
    }

    public ICommand Create<T>(object arg1)
    {
        return Create<T>(new[] {arg1});
    }

    public ICommand Create<T>(object arg1, object arg2)
    {
        return Create<T>(new[] {arg1, arg2});
    }

    public ICommand Create<T>(object arg1, object arg2, object arg3)
    {
        return Create<T>(new[] {arg1, arg2, arg3});
    }

    public ICommand Create<T>(object[] arguments)
    {
        return (ICommand)Activator.CreateInstance(GetRegisteredType<T>(), arguments);
    }

    public static Type GetRegisteredType<T>()
    {
        return ObjectFactory.Model.DefaultTypeFor(typeof (T));
    }
}

I think I solved the problem using a small utility class. This class gets the concrete type from ObjectFactory and uses this type to construct the instance according to the parameters past into the factory method. Now on the 'client' side I use ObjectFactory to create an instance of CommandFactory. The implementation of CommandFactory is in another solution and thus the 'client solution' remains independent of the 'server' solution.

public class CommandFactory
{

    public ICommand Create<T>()
    {
        return Create<T>(new object[] {});
    }

    public ICommand Create<T>(object arg1)
    {
        return Create<T>(new[] {arg1});
    }

    public ICommand Create<T>(object arg1, object arg2)
    {
        return Create<T>(new[] {arg1, arg2});
    }

    public ICommand Create<T>(object arg1, object arg2, object arg3)
    {
        return Create<T>(new[] {arg1, arg2, arg3});
    }

    public ICommand Create<T>(object[] arguments)
    {
        return (ICommand)Activator.CreateInstance(GetRegisteredType<T>(), arguments);
    }

    public static Type GetRegisteredType<T>()
    {
        return ObjectFactory.Model.DefaultTypeFor(typeof (T));
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文