RavenDB和构造函数注入

时间:2012-05-19 04:49:24

标签: dependency-injection ravendb constructor-injection

在我的项目中,我有以下PageCache实体,它存储在RavenDB中:

public class PageCache
{
    private readonly IHtmlDocumentHelper htmlDocumentHelper;

    public string Id { get; set; }
    public string Url { get; set; }

    public PageCache(IHtmlDocumentHelper htmlDocumentHelper, string url)
    {
        this.htmlDocumentHelper = htmlDocumentHelper;
        this.Url = url;
    }
}

我正在使用Castle Windsor在运行时注入IHtmlDocumentHelper实现。此成员用于PageCache类中定义的方法,为简单起见,我从上面的代码段中删除了该方法。

当我使用构造函数创建PageCache对象时,一切正常。但是在我的代码的其他地方,我从RavenDB加载PageCache个对象:

public PageCache GetByUrl(string url)
{
    using (var session = documentStore.OpenSession())
    {
        return session.Query<PageCache>()
                      .Where(x => x.Url == url)
                      .FirstOrDefault();
    }
}

我的问题是我从RavenDB返回的对象没有设置htmlDocumentHelper成员,导致依赖它的PageCache方法无法使用。

换句话说:当我从存储在RavenDB中的文档中加载对象时,它不会使用我的构造函数来构建对象,因此不会通过构造函数注入初始化私有成员。

我在这里做错了吗?你会如何解决这个问题?


我最终使用Ayende提出的解决方案。我在评论中提到的循环依赖问题仅在我使用DocumentStore在温莎注册UsingFactoryMethod()时出现。当我使用Windsor的DependsOn()OnCreate()直接在DocumentStore内配置和初始化Register()时,这个问题就奇怪地消失了。

我的容器现在正在初始化如下:

WindsorContainer container = new WindsorContainer();

container.Register(
    // Register other classes, such as repositories and services.
    // Stripped for the sake of clarity.
    // ...

    // Register the CustomJsonConverter:
    Component.For<CustomJsonConverter>().ImplementedBy<CustomJsonConverter>(),

    // The following approach resulted in an exception related to the circular
    // dependencies issue:
    Component.For<IDocumentStore>().UsingFactoryMethod(() =>
        Application.InitializeDatabase(container.Resolve<CustomJsonConverter>()))

    // Oddly enough, the following approach worked just fine:
    Component.For<IDocumentStore>().ImplementedBy<DocumentStore>()
        .DependsOn(new { Url = @"http://localhost:8080" })
        .OnCreate(new Action<IDocumentStore>(store =>
            store.Conventions.CustomizeJsonSerializer = serializer =>
                serializer.Converters.Add(container.Resolve<CustomJsonConverter>())))
        .OnCreate(new Action<IDocumentStore>(store =>
            store.Initialize()))
        .OnDestroy(new Action<IDocumentStore>(store =>
            store.Dispose()))
    );

虽然它似乎工作正常,但我觉得奇怪的是必须从container.Resolve<CustomJsonConverter>()方法中调用container.Register()

这是注册依赖项的合法方法吗?

1 个答案:

答案 0 :(得分:2)

基督教, 我们不能使用你的ctor,我们不知道该放什么。

相反,您可以使用此技术告诉RavenDB如何创建对象: http://james.newtonking.com/projects/json/help/CustomCreationConverter.html

然后你可以使用documentStore.Conventison.CustomizeSerializer

连接它