Replacing service implementations

Topics: Developer Forum
Jun 2, 2010 at 8:22 AM

Hi guys,

What's the expected way to replace a service implementation with your own? For instance, 

[Service(typeof(ISessionProvider))]
public class SessionProvider : ISessionProvider

in N2 means that SessionProvider will always get registered within the DI container. I can add the same attribute to my class, but how can I make it the default class to use rather than the built in one?

The only way I've been able to do it so far is modify the N2 source to remove the [Service] attribute on your default implementation, and then call AddComponent() manually on the appropriate components that I actually want?

Thanks

James

Coordinator
Jun 2, 2010 at 9:17 PM

You can replace services using config like this.

<n2>
	<engine>
		<components>
			<add service="N2.Persistence.IPersister, N2" implementation="X, N2.Templates.Mvc"/>
		</components>
	</engine>
Oct 20, 2011 at 8:33 PM
Edited Oct 20, 2011 at 8:35 PM

I just thought I'd add a note in here for anyone having any problems with this when using generic interfaces, IRepository<,> in this example.  In this case you have to use notation similar to the following:

<add service="N2.Persistence.IRepository`2[[System.Int32],[N2.ContentItem]], N2" implementation="My.Namespace.MyContentItemRepositoryImplementation, MyAssembly"/>
The `2 refers to the number of arguments then the stuff in the square brackets is obviously the types.

Also worth noting that using this configuration AND the Service attribute on the class (i.e. [Service(typeof(IRepository<int, ContentItem>), Key = "n2.repository.ContentItem")] won't work as it effectively attempts to add the implementation to the DI container twice (I think...).

Coordinator
Oct 25, 2011 at 9:19 PM

Hi, there's also a new way of replacing services using the [Service(Replaces = typeof(ServiceTypeToReplace))]

Apr 27, 2012 at 10:20 AM
Edited Apr 27, 2012 at 10:37 AM

I am trying to use new way of replacing services, but I have problems.

When I use <engine><components><add service it work flawlessly. However, when trying with attribute

 

	[Service(Replaces = typeof(N2.Persistence.TagsRepository))]
	public class MyTagRepository : N2.Persistence.TagsRepository

 

I get

 

No component for supporting the service N2.Persistence.TagsRepository was found

[ComponentNotFoundException: No component for supporting the service N2.Persistence.TagsRepository was found]
   Castle.MicroKernel.DefaultKernel.Resolve(Type service) +138
   Castle.Windsor.WindsorContainer.Resolve(Type service) +13
   N2.Engine.Castle.WindsorServiceContainer.Resolve(Type type) +13
   N2.Engine.ContentEngine.Resolve() +63
   N2.Details.EditableTagsAttribute.GetTagsText(ContentItem item) +42
   N2.Details.EditableTagsAttribute.UpdateEditor(ContentItem item, Control editor) +34
   N2.Edit.EditManager.UpdateEditors(ItemDefinition definition, ContentItem item, IDictionary`2 addedEditors, IPrincipal user) +250
   N2.Edit.EditableAdapter.LoadAddedEditors(ItemDefinition definition, ContentItem item, IDictionary`2 addedEditors, IPrincipal user) +29
   N2.Web.UI.WebControls.ItemEditor.CreateChildControls() +198
   System.Web.UI.Control.EnsureChildControls() +102
   N2.Web.UI.WebControls.ItemEditor.set_CurrentItem(ContentItem value) +144
   N2.Edit.Edit.InitItemEditor() +386
   N2.Edit.Edit.OnInit(EventArgs e) +102
   System.Web.UI.Control.InitRecursive(Control namingContainer) +140
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +480

Managed to solve it. In case anyone needs it, proper attribute is

 

[Service(typeof(TagsRepository), Replaces = typeof(TagsRepository))]

Coordinator
Apr 28, 2012 at 6:00 PM

Try specifying the service type:

[Service(
typeof(N2.Persistence.TagsRepository),
Replaces = typeof(N2.Persistence.TagsRepository))]