Dependent injection – RavendB and constructor injection

In my project, I have the following PageCache entity, which is stored in RavenDB:

public class PageCache< br />{
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;
}
}

< p>I am using Castle Windsor to inject the IHtmlDocumentHelper implementation at runtime. This member is used for the method defined in the PageCache class. For simplicity, I removed the method from the above code snippet.

When I When using the constructor to create a PageCache object, everything works fine. But elsewhere in my code, I loaded the PageCache object from RavenDB:

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

My problem is that the object I return from RavenDB does not have htmlDocumentHelp set er member, the PageCache method that depends on it is unavailable.

In other words: when I load an object from a document stored in RavenDB, it will not use my constructor to build the object, so it doesn’t Will initialize private members through constructor injection.

Am I doing something wrong here? How would you solve this problem?

I finally used the solution proposed by Ayende. The circular dependency problem I mentioned in the comments only appeared when I used UsingFactoryMethod() to register DocumentStore in Windsor. When I used Windsor’s DependsOn() and When OnCreate() is used to configure and initialize DocumentStore directly in Register(), this problem disappears strangely.

My container is now being initialized as follows:

< pre>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().ImplementedBy(),

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

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

Although it seems to work fine, I had to download from container.Register () method to call container.Resolve().

Is this a legal way to register dependencies?

Christianity,
We can’t use your ctor, we don’t know what to put. < p>

Instead, you can use this technique to tell RavenDB how to create objects:
http://james.newtonking.com/projects/json/help/CustomCreationConverter.html

Then you can use documentStore.Conventison.CustomizeSerializer to connect it

In my project, I have the following PageCache entity, which is stored in RavenDB:

< /p>

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;
}
}

I am using Castle Windsor to inject the IHtmlDocumentHelper implementation at runtime. This member is used for the methods defined in the PageCache class. For simplicity, I started from the above The method was removed from the code snippet.

When I used the constructor to create a PageCache object, everything was fine. But elsewhere in my code, I loaded the PageCache object from RavenDB:

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

My problem is that the object I returned from RavenDB does not have the htmlDocumentHelper member set, which makes the PageCache method that depends on it unavailable.

In other words: when I load an object from a document stored in RavenDB, it will not use my constructor to build the object, so it will not initialize private members through constructor injection.

Am I doing something wrong here? How would you solve this problem?

I finally used the solution proposed by Ayende. The circular dependency problem I mentioned in the comments only appeared when I used UsingFactoryMethod() to register DocumentStore in Windsor. When I used Windsor’s DependsOn() and When OnCreate() is used to configure and initialize DocumentStore directly in Register(), this problem disappears strangely.

My container is now being initialized as follows:

< pre>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().ImplementedBy(),

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

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

Although it seems to work fine, I had to download from container.Register () method to call container.Resolve().

Is this a legal way to register dependencies?

Christianity,
We can’t use your ctor, we don’t know what to put.

On the contrary, you You can use this technique to tell RavenDB how to create objects:
http://james.newtonking.com/projects/json/help/CustomCreationConverter.html

Then you can use documentStore.Conventison.CustomizeSerializer to connect It

Leave a Comment

Your email address will not be published.