在 StructureMap 中使用开放泛型进行自定义构造

发布于 2024-09-24 09:40:25 字数 849 浏览 0 评论 0原文

我有一个典型的存储库接口,IRepository,以及许多具体的存储库。大多数具体存储库如下所示:

class ConcreteRepository<T> : IRepository<T> { .. }

这些很容易使用 StructureMap 注册:

For(typeof(IRepository<>)).Use(typeof(ConcreteRepository<>));

但是,我选择的一些具体存储库如下所示:

class AbnormalRepository<T1, T2> : IRepository<T1>, IAbnormal<T2> { .. }

我仍然想将这些异常存储库用作 IRepository s,因此对于这些,我目前正在使用特殊规则:

// this sucks!
For(typeof(IRepository<Foo1>)).Use(typeof(AbnormalRepository<Foo1, Bar1>));
For(typeof(IRepository<Foo2>)).Use(typeof(AbnormalRepository<Foo2, Bar2>));

如果我可以指定一个 StructureMap 可以用来构建我的存储库的函数,那就太好了,因为我知道我的所有异常存储库都实现了 IAbnormal;。有什么想法吗?

I have a typical repository interface, IRepository<T>, and lots of concrete repositories. Most of the concrete repositories look like this:

class ConcreteRepository<T> : IRepository<T> { .. }

These are easy to register with StructureMap:

For(typeof(IRepository<>)).Use(typeof(ConcreteRepository<>));

However, a select few of my concrete repositories look like this:

class AbnormalRepository<T1, T2> : IRepository<T1>, IAbnormal<T2> { .. }

I still want to use these abnormal repositories as IRepository<T>s, so for these I'm currently using special rules:

// this sucks!
For(typeof(IRepository<Foo1>)).Use(typeof(AbnormalRepository<Foo1, Bar1>));
For(typeof(IRepository<Foo2>)).Use(typeof(AbnormalRepository<Foo2, Bar2>));

It would be nice if I could just specify a function that StructureMap could use to construct my repositories, since I know that all of my abnormal repositories implement IAbnormal<T>. Any ideas?

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

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

发布评论

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

评论(2

自在安然 2024-10-01 09:40:25

创建自定义 IRegistrationConvention 并从容器配置的 Scan() 方法中调用它。

您可以在另一个 stackoverflow 问题上看到讨论的示例:

StructureMap IRegistrationConvention to注册非默认命名约定?

您还可以在 StructureMap 源代码本身中看到许多 IRegistrationConvention 示例。

Create a custom IRegistrationConvention and call it from within the Scan() method of your container configuration.

You can see an example of this discussed on another stackoverflow question:

StructureMap IRegistrationConvention to register non default naming convention?

You can also see a number of IRegistrationConvention examples within the StructureMap source code itself.

横笛休吹塞上声 2024-10-01 09:40:25

我没有完全遵循您的用例,但您可以使用函数(实际上是 lambda)来构造您的对象。使用两个重载之一:

// lambda with no params
For<IRepository<Foo1>>().Use(() => { ... });
// context is a StructureMap SessionContext
For<IRepository<Foo1>>().Use(context => { ... }); 

要查看 SessionContext 可用的内容,请查看 http://structuralmap .github.com/structuralmap/UsingSessionContext.htm

添加:

using System;
using NUnit.Framework;
using StructureMap;

namespace SMTest2
{
    public interface IRepository<T> {}
    public class AbnormalRepository<T,T2> : IRepository<T>{ }

    [TestFixture]
    public class TestOpenGeneric
    {
        private IContainer _container   ;

        [SetUp]
        public void DescribeContainer()
        {
            _container = new Container(cfg => 
                cfg.For(typeof (IRepository<>)).Use(ctx => new AbnormalRepository<String, int>()));
        }

        [Test]
        public void TestItWorks()
        {
            var stringVector = _container.GetInstance(typeof (IRepository<>));
            Assert.IsInstanceOf<AbnormalRepository<String,int>>(stringVector);
        }
    }
}

I'm not following your use case all the way, but you can use a function (lambda actually) to construct your object. Use either of the two overloads:

// lambda with no params
For<IRepository<Foo1>>().Use(() => { ... });
// context is a StructureMap SessionContext
For<IRepository<Foo1>>().Use(context => { ... }); 

To see what is available off SessionContext, check out http://structuremap.github.com/structuremap/UsingSessionContext.htm

ADDED:

using System;
using NUnit.Framework;
using StructureMap;

namespace SMTest2
{
    public interface IRepository<T> {}
    public class AbnormalRepository<T,T2> : IRepository<T>{ }

    [TestFixture]
    public class TestOpenGeneric
    {
        private IContainer _container   ;

        [SetUp]
        public void DescribeContainer()
        {
            _container = new Container(cfg => 
                cfg.For(typeof (IRepository<>)).Use(ctx => new AbnormalRepository<String, int>()));
        }

        [Test]
        public void TestItWorks()
        {
            var stringVector = _container.GetInstance(typeof (IRepository<>));
            Assert.IsInstanceOf<AbnormalRepository<String,int>>(stringVector);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文