While scanning trough DotNetNuke’s source I noticed it provides a clean abstraction for a component (DI) container: DotNetNuke.ComponentModel.IContainer and DotNetNuke.ComponentModel.AbstractContainer.
The default implementation DNN provides (SimpleContainer) is not sufficient for the things I wanted to do with it (auto registration, custom lifetime management, etc.). So instead of using CommonServiceLocator in my framework, I went with writing a custom implementation of IContainer utilizing the Castle Windsor container.
Following is an example implementation, feel free to use the code in your own project:
You should know how to change the default container DotNetNuke uses. If not, then you probably won’t need it and can continue reading just for fun ?
As you can see this is called CastleSimpleContainer. In DotNetNukeMVP a more extended implementation is provided to allow a common way for more flexible registration of components.
1 // ---------------------------------------------------------------------------------------------------------------------
2 // <copyright file="CastleSimpleContainer.cs" company="RawSoft">
3 // Copyright (c) RawSoft. All rights reserved.
4 // </copyright>
5 // <summary>
6 // Defines the CastleSimpleContainer type.
7 // </summary>
8 // ---------------------------------------------------------------------------------------------------------------------
9 namespace DotNetNukeMVP.Castle
10 {
11 using System;
12 using System.Collections;
13 using System.Collections.Generic;
14
15 using DotNetNuke.ComponentModel;
16
17 using global::Castle.Core;
18 using global::Castle.Windsor;
19
20 public class CastleSimpleContainer : AbstractContainer
21 {
22 private readonly string containerName;
23
24 private readonly IWindsorContainer container;
25
26 private readonly IDictionary<string, IDictionary> componentDependencies = new Dictionary<string, IDictionary>();
27
28 public CastleSimpleContainer()
29 : this(new WindsorContainer())
30 {
31 }
32
33 public CastleSimpleContainer(IWindsorContainer container)
34 : this(string.Format("Container_{0}", Guid.NewGuid()), container)
35 {
36 }
37
38 public CastleSimpleContainer(string name, IWindsorContainer container)
39 {
40 this.containerName = name;
41 this.container = container;
42 }
43
44 public IWindsorContainer InnerContainer
45 {
46 get
47 {
48 return this.container;
49 }
50 }
51
52 public override string Name
53 {
54 get
55 {
56 return this.containerName;
57 }
58 }
59
60 public override void RegisterComponentSettings(string name, IDictionary dependencies)
61 {
62 componentDependencies[name] = dependencies;
63 }
64
65 public override object GetComponent(string name)
66 {
67 if (!this.container.Kernel.HasComponent(name))
68 {
69 return null;
70 }
71
72 try
73 {
74 return this.container.Resolve(name);
75 }
76 catch
77 {
78 }
79
80 return null;
81 }
82
83 public override object GetComponent(string name, Type contractType)
84 {
85 if (!this.container.Kernel.HasComponent(contractType))
86 {
87 return null;
88 }
89
90 try
91 {
92 return this.container.Resolve(name, contractType);
93 }
94 catch
95 {
96 }
97
98 return null;
99 }
100
101 public override IDictionary GetComponentSettings(string name)
102 {
103 if (componentDependencies.ContainsKey(name))
104 {
105 return componentDependencies[name];
106 }
107
108 return null;
109 }
110
111 public override void RegisterComponent(string name, Type contractType, Type componentType, ComponentLifeStyleType lifestyle)
112 {
113 this.container.AddComponentLifeStyle(name, contractType, componentType, GetLifeStyleType(lifestyle));
114 }
115
116 public override void RegisterComponentInstance(string name, Type contractType, object instance)
117 {
118 this.container.Kernel.AddComponentInstance(name, contractType, instance);
119 }
120
121 public override object GetComponent(Type contractType)
122 {
123 try
124 {
125 return this.container.Resolve(contractType);
126 }
127 catch
128 {
129 }
130
131 return null;
132 }
133
134 private static LifestyleType GetLifeStyleType(ComponentLifeStyleType lifeStyleType)
135 {
136 LifestyleType scope = lifeStyleType == ComponentLifeStyleType.Singleton
137 ? LifestyleType.Singleton
138 : LifestyleType.Transient;
139 return scope;
140 }
141 }
142 }