I've got a bunch of classes written like this:
public class MyService1 {
public MyService1(MyService1Settings settings, <service-dependent list of dependencies filled by Windsor>) { ... }
}
which are registered in the Windsor like this:
container.Register(
...
Component.For<MyService1>().LifestyleTransient(),
Component.For<MyService2>().LifestyleTransient(),
...
);
container doesn't have any of the MyServiceXSettings types registered, so the only way to get a service is to resolve it from container like this:
TService service = windsorContainer.Resolve<TService>(new { settings });
The thing is, depending on the parameters in the settings object, one of the services tries to acquire another instance of its type with different settings object.
Something along the lines of:
public class MyService2 {
public MyService2(MyService2Settings settings, <service-dependent list of dependencies filled by Windsor>)
{
this.uplink = settings.Counter == 1
? new AnotherUplink()
: new RecursiveUplink(
container.Resolve<MyService2>(new {
settings = new MyService2Settings(settings.Counter - 1)
});
}
}
This recursive dependency chain is finite (and is about 6 instances deep), but Windsor throws an exception when the first service tries to get another one, stating that it's a circular dependency.
I've advertised all the services as having Transient lifestyles and requesting them with custom parameters. Can I at least specify the maximum allowed depth of the recursion? Or am I missing another way I can do it?
another requirement: I can't use typed factories, because I've got quite many different types of those services, so generating many factory interfaces individually for those services would be undesired.
container doesn't have any of the MyServiceXSettings types registered,
so the only way to get a service is to resolve it from container like
this:
You may also use a dedicated SubResolver or a DependsOn during component registration.
Executing code in a constructor(rather than a simply variable assignement) is a smell, even worst using the container: it should never leak in the application layer.
At the first sight, it seems you are using the settings only to choose the proper component within the constructor: that should be done at CompositionRoot, using a TypedFactory or also by naming convention(you may have multiple component registered for same intercace, but a given parameter name drives the component selection)
As per this answer, I went with lazy resolution.
/// <summary>
/// Represents single component instance producer.
/// </summary>
/// <typeparam name="TComponent">type of the component to create</typeparam>
public interface IComponentCreator<TComponent>
{
/// <summary>
/// Gets the created component.
/// </summary>
TComponent Component { get; }
}
/// <summary>
/// Creates the component only when it's first requested.
/// </summary>
/// <typeparam name="TComponent">type of the component to create</typeparam>
public class LazyCreator<TComponent> : IComponentCreator<TComponent>
{
private readonly Func<TComponent> creatingFunction;
private bool created;
private TComponent component;
public LazyCreator(Func<TComponent> creatingFunction)
{
this.creatingFunction = creatingFunction;
}
public TComponent Component
{
get
{
if (!created)
{
component = creatingFunction();
created = true;
}
return component;
}
}
}
/// <summary>
/// Returns already created component.
/// </summary>
/// <typeparam name="TComponent">type of the component</typeparam>
public class ComponentContainer<TComponent> : IComponentCreator<TComponent>
{
private readonly TComponent component;
public ComponentContainer(TComponent component)
{
this.component = component;
}
public TComponent Component
{
get { return component; }
}
}
Related
Is there a way I can acheieve the following in a shorter way than explicitly register those types one by one:
builder.RegisterType<Repo1>().Keyed<IRepository>(typeof(Repo1));
builder.RegisterType<Repo2>().Keyed<IRepository>(typeof(Repo2));
builder.RegisterType<Repo3>().Keyed<IRepository>(typeof(Repo3));
..
Registering each repository as IRepository interface with it's type as key, so that I can use IIndex<Type, IRepository>
Thanks in advance
You could register a function that will return a repository for a given type, to use in your Unit of Work. Func<Type, IRepository> can be registered in Autofac and injected into your Unit of Work.
// register your services as per Nico's answer
builder.Register...
// register a factory with Autofac
builder.Register<Func<Type, IRepository>>(x => {
var context = x.Resolve<IComponentContext>();
return y => {
return (IRepository) context.Resolve(y);
};
});
// use the factory in your Unit of Work
class UnitOfWork
{
readonly Func<Type, IRepository> _factory;
public void SomeMethod(object o)
{
var repository = _factory(o.GetType());
repository.DoSomething(o);
}
}
Taking a little inspiration from MEF , I have created a similar "Export Attribute" to achieve this in autofac.
You can create an Export attribute and use it on each implementation of IRepository as
[Export(typeof(IRepository))]
.
e.g. [Export(typeof(IRepository))]
class Repo1:IRepository
{}
At the time of registration, simply extract the type and using RegisterGeneric(), register your components.
/// <summary>
/// Export attribute to allow registering components using autofac.
/// This attribute must be used for all pluggable components that require to be discovered dynamically.
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class ExportAttribute:Attribute
{
private Type type;
public ExportAttribute(Type type)
{
this.type = type;
}
/// <summary>
/// Provides the type (any interface) of Export
/// </summary>
public Type Type { get { return this.type; } }
}
/// <summary>
/// Registers components based on Export attribute containing their type information
/// </summary>
private void BuildContainer()
{
var allAssemblies = AssemblyInitializer.GetLoadedPlugins();
allAssemblies.ForEach(assembly =>
{
var allTypes = assembly.GetTypes().Where(a => a.GetCustomAttribute(typeof(ExportAttribute)) != null).ToList<Type>();
allTypes.ForEach(y =>
{
var classType = ((ExportAttribute)(y.GetCustomAttribute(typeof(ExportAttribute)))).Type;
if (!classType.IsInterface || !classType.IsAbstract || !classType.IsPublic) return;
if (classType.Equals(typeof(IRepository<>)))
{
builder.RegisterGeneric(y.GetTypeInfo()).Named(y.GetTypeInfo().Name, typeof(IRepository<>));
}
// Handle code for any other specific Interfaces
});
});
this.Container = builder.Build();
}
Not really sure if I am following the question correctly howevery typically IRepository points to a data repository with generic functions (insert, update, delete etc). However autofac keyed services are used to register the service with key names (or any key type). If this is the case you will have to come up with a solution that can locate all your Repo types and register them individually in a loop. This could be achieved using Reflection. However each object Repo1, Repo2 etc, will need a common derivative.
For example lets say each Repo object derrives from the interface IRepo then we can use reflection to find all instances of the IRepo interface where the type is a class then loop through each instance registering it to your container. Something like.
var iRepoType = typeof(IRepo);
var repoTypes = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => type.IsClass && iRepoType.IsAssignableFrom(type))
.ToList();
foreach(var repoType in repoTypes)
{
builder.RegisterType(repoType).Keyed<IRepository>(repoType);
}
Now personally this doesn't make any sense as when you look at this keyed service you are saying when I pass in the key typeof(Repo1) I want Repo1. Therefore isn't this the same as registering each type of Repository differently without using Keyed services?
I have posted an answer in code review talking about Repository patterns and classes that may also be some interest.
I'm using a Unity IoC container to do Dependency Injection. I designed my system around the idea that, at least for a single resolution, all types in the hierarchy would behave as singletons, that is, same type resolutions within that hierarchy would lead to the same instances.
However, I (a) would like to scan my assemblies to find types and (b) don't want to explicitly tell unity that every type is to be resolved as a singleton when registering types in the configuration file.
So, is there a way to tell unity to treat all registered mappings as singleton?
In case anyone is still looking for this... The following extension will change the default, while still allowing you to override with some other manager:
/// <summary>
/// This extension allows the changing of the default lifetime manager in unity.
/// </summary>
public class DefaultLifetimeManagerExtension<T> : UnityContainerExtension where T : LifetimeManager
{
/// <summary>
/// Handle the registering event
/// </summary>
protected override void Initialize()
{
Context.Registering += this.OnRegister;
}
/// <summary>
/// Remove the registering event
/// </summary>
public override void Remove()
{
Context.Registering -= this.OnRegister;
}
/// <summary>
/// Handle the registration event by checking for null registration
/// </summary>
private void OnRegister(object sender, RegisterEventArgs e)
{
if (e.LifetimeManager == null)
{
var lifetimeManager = (LifetimeManager)Activator.CreateInstance(typeof (T));
// Set this internal property using reflection
lifetimeManager
.GetType()
.GetProperty("InUse", BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(lifetimeManager, true);
Context.Policies.Set<ILifetimePolicy>(lifetimeManager, new NamedTypeBuildKey(e.TypeTo, e.Name));
if (lifetimeManager is IDisposable)
{
Context.Lifetime.Add(lifetimeManager);
}
}
}
}
You could add a Unity extension at the 'Lifetime' stage of the resolution pipeline and in it always use a ContainerControlledLifetimeManager instance.
Edit: In fact this post has the exact example:
https://unity.codeplex.com/discussions/352179
In a continuation of my previous thread, I have found that a lot of my classes contain collections. Eg:
Engine - contains collection of pistons - piston - contains collection of xyz parts
Thus there is a hierarchy, as every component contains a collection of parts, which goes on and on.
This is a coding scenario I have not come across before. Constantly writing code like so:
class Part (Replace Part with apt name)
{
List<APart> parts ...
}
And then the same for APart, as that contains a collection of inner parts, is very tedious and therefore making me question whether this is the right way to code.
Is there a better way to write this sort of code? Anything like AOP etc I am open to (Though AOP is for cross-cutting concerns).
One thought:
Your Engine class could contain a PistonsManager class, which manages the list of Pistons. The PistonsManager could contain all of the logic to modify the list and shield the Engine class from having to think about Pistons. By the same logic, your PistonsManager class could contain an XYZPartsManager. This way you aren't programming list logic/management into your Engine logic, but have classes to do that. It might make readability and make the logic flow nicely.
Sometimes coding is just tedious. However, there are often patterns that can be ferreted out of an implementation.
We have a situation similar to yours and discovered that there was an underlying recursive pattern. So we implemented a base class (call it Part) that itself can contain a List(Of Part). This can be as deep as needed.
The collection classes for specific class implementations are either generic collections of the specific type or implement an interface that allows us to get at specific data in the class (we had to implement the interface mechanism due to collection collisions in WCF).
The upshot is that you will probably have a lot of discrete Part inheritors, but your will will be a common way to instantiate, process, and traverse your elements with a common set of code.
Update
This is a severely contrived example, but one that should get you pointed in the right direction. In our application, we use a substantial amount of reflection and table-mapped class names in order to severely reduce the amount of repetitive code. This example reflects some of that behavior, but not all.
This example basically shows how you can have a generic part class which contains a recursive collection of parts which are indexed at the part type level. In other words, you will have Engine and Engine will have a collection of part collections indexed by part type. For example, Engine could have a collection of Pistons, a collection of hoses, etc. This design is obviously optional, but does make it somewhat easier to process.
Here are the main classes:
/// <summary>
/// The base part collection
/// </summary>
/// <remarks></remarks>
public class PartBase
{
/// <summary>
/// The key for the record, such as a recordid
/// </summary>
/// <value></value>
/// <returns></returns>
/// <remarks></remarks>
public virtual string CollectionKey {get; set;}
public PartBase() : base()
{
m_cParts = new PartBaseCollections();
}
public virtual void InitializeFromDataRow(DataRow oRow)
{
// ToDo: Either implement generic column/datarow mapping through reflection or have each class override this method
}
private PartBaseCollections m_cParts;
public PartBaseCollections Parts
{
get
{
return m_cParts;
}
}
public PartBaseCollection GetParts(string sTableName)
{
if (this.Parts.Contains(sTableName))
{
return this.Parts(sTableName);
}
else
{
PartBaseCollection cParts = new PartBaseCollection(sTableName);
this.Parts.Add(cParts);
return cParts;
}
}
public void AddParts(DataSet dsData)
{
foreach (DataTable oTable in dsData.Tables)
{
PartBaseCollection cParts = null;
cParts = GetParts(oTable.TableName);
cParts.AddRecordsFromTable(oTable);
}
}
}
/// <summary>
/// A collection of PartBases keyed by a value, such as a table name (for example, Pistons)
/// </summary>
/// <remarks></remarks>
public class PartBaseCollection : System.Collections.ObjectModel.KeyedCollection<string, PartBase>
{
public string CollectionKey {get; set;}
public Type RecordType {get; set;}
public PartBaseCollection(string TableName)
{
this.CollectionKey = TableName;
// Assume that the TableName is a class in the current namespace
RecordType = Type.GetType(this.GetType().Namespace + "." + TableName, false, true);
}
protected override string GetKeyForItem(PartBase item)
{
return item.CollectionKey;
}
public PartBase ManufactureRecord()
{
return Activator.CreateInstance(this.RecordType);
}
public void AddRecordsFromTable(DataTable oTable)
{
foreach (DataRow oRow in oTable.Rows)
{
PartBase oPart = null;
oPart = ManufactureRecord();
oPart.InitializeFromDataRow(oRow);
this.Add(oPart);
}
}
}
/// <summary>
/// All of the PartBaseCollection elements for a given PartBase
/// </summary>
/// <remarks></remarks>
public class PartBaseCollections : System.Collections.ObjectModel.KeyedCollection<string, PartBaseCollection>
{
protected override string GetKeyForItem(PartBaseCollection item)
{
return item.CollectionKey;
}
}
public class Engine : PartBase
{
}
public class Piston : PartBase
{
}
And here is an example of creating the engine:
public void CreateEngine()
{
DataSet dsData = new DataSet();
DataTable oTable = new DataTable("Piston");
dsData.Tables.Add(oTable);
Engine oEngine = new Engine();
oEngine.AddParts(dsData);
}
sounds like the composite design pattern - consider looking at the iterator design pattern and perhaps the visitor design pattern as these usually go together.
I have a class with internal constructor and want to Resolve it from Unity (2.0).
public class MyClass {
internal MyClass(IService service) {
}
}
then I'm doing
_container.Resolve<MyClass>();
when I do so I have an exception
Exception is: InvalidOperationException - The type MyClass cannot be constructed.
IService is registered and the only problem is that constructor is internal.
I really want this class to be public, but I want it to be creatable only via a factory (in which I'm actually calling container.Resolve<MyClass>()).
Is there a way to make Unity see that internal constructor? Like InternalsVisibleTo or something?
I dug a little into how you might extend Unity for this purpose, and found some interesting information.
First, it seems that Unity selects which constructor to use by internally resolving an IConstructorSelectorPolicy. Included in Unity is the public abstract class ConstructorSelectorPolicyBase<TInjectionConstructorMarkerAttribute>, which includes this gem:
/// <summary>
/// Choose the constructor to call for the given type.
/// </summary>
/// <param name="context">Current build context</param>
/// <param name="resolverPolicyDestination">The <see cref='IPolicyList'/> to add any
/// generated resolver objects into.</param>
/// <returns>The chosen constructor.</returns>
public SelectedConstructor SelectConstructor(IBuilderContext context, IPolicyList resolverPolicyDestination)
{
Type typeToConstruct = context.BuildKey.Type;
ConstructorInfo ctor = FindInjectionConstructor(typeToConstruct) ?? FindLongestConstructor(typeToConstruct);
if (ctor != null)
{
return CreateSelectedConstructor(context, resolverPolicyDestination, ctor);
}
return null;
}
FindInjectionConstructor and company are private static methods in this class which ultimately end up calling Type.GetConstructors (the overload with no parameters, which only returns public constructors). This tells me that if you can arrange for Unity to use your own constructor selector policy, which would be able to select any constructor, you are golden.
There is good documentation about how to make and utilize your own container extensions, so I imagine it's quite possible to make your own CustomConstructorSelectorPolicy that includes the relevant portions of DefaultUnityConstructorSelectorPolicy (which derives from the abstract base class and is the default unless you register something else) and ConstructorSelectorPolicyBase (deriving from this directly would probably not work well because key methods are not virtual, but you can reuse the code).
Therefore I 'd say it's doable with a moderate amount of hassle, but the end result would be quite "pure" from an engineering point of view.
Unity will only look at public constructors, so you need to make this constructor public.
I really want this class to be public,
but I want it to be creatable only via
a factory
In that case, create a factory:
public class MyClassFactory : IMyClassFactory
{
private readonly IService service;
public MyClassFactory(IService service)
{
this.service = service;
}
MyClass IMyClassFactory.CreateNew()
{
return new MyClass(this.service);
}
}
And register:
_container.Register<IMyClassFactory, MyClassFactory>();
And resolve:
_container.Resolve<IMyClassFactory>().CreateNew();
You can also use Unity's InjectionFactory:
container.Register<MyClass>(new InjectionFactory(c =>
{
return new MyClass(c.Resolve<IService>());
}));
For this to work the assembly that holds this code should be able to see the internals of the assembly that holds the MyClass. In other words the MyClass assembly should be marked with InternalsVisibleTo.
What would also work is the following:
public static class MyClassFactory
{
public static MyClass CreateNew(IService service)
{
return new MyClass(service);
}
}
container.Register<MyClass>(new InjectionFactory(c =>
{
return MyClassFactory.Create(c.Resolve<IService>());
}));
Although you won't have to make the constructor public, it is a great way to obfuscate your code :-)
Just make the class internal and the constructor public...
Interface public
Class internal
Constructor of class public.
It's possible there are workarounds/hacks that would allow you to do this with Unity 9I don't know if any), but in general if you want a class to be managed by Unity (or any IOC container), it needs to be public with a public constructor.
One option might be to make an abstract factory that creates the class that has a public constructor, and keep the class's constructor internal. The downside is then your factory will be managed by Unity, but your class itself will not.
I trying to make automatic variables available to Excel VBA (like ActiveSheet or ActiveCell) also available to PowerShell as 'automatic variables'. PowerShell engine is hosted in an Excel VSTO add-in and Excel.Application is available to it as Globals.ThisAddin.Application. I found this thread here on StackOverflow and started created PSVariable derived classes like:
public class ActiveCell : PSVariable
{
public ActiveCell(string name) : base(name) { }
public override object Value
{
get
{
return Globals.ThisAddIn.Application.ActiveCell;
}
}
}
public class ActiveSheet : PSVariable
{
public ActiveSheet(string name) : base(name) { }
public override object Value
{
get
{
return Globals.ThisAddIn.Application.ActiveSheet;
}
}
}
and adding their instances to the current POwerShell session:
runspace.SessionStateProxy.PSVariable.Set(new ActiveCell("ActiveCell"));
runspace.SessionStateProxy.PSVariable.Set(new ActiveSheet("ActiveSheet"));
This works and I am able to use those variables from PowerShell as $ActiveCell and $ActiveSheet (their value change as Excel active sheet or cell change). Then I read PSVariable documentation here and saw this:
"There is no established scenario for deriving from this class. To programmatically create a shell variable, create an instance of this class and set it by using the PSVariableIntrinsics class."
As I was deriving from PSVariable, I tried to use what was suggested:
PSVariable activeCell = new PSVariable("ActiveCell");
activeCell.Value = Globals.ThisAddIn.Application.ActiveCell;
runspace.SessionStateProxy.PSVariable.Set(activeCell);
Using this, $ActiveCell appears in my PowerShell session, but its value doesn't change as I change the active cell in Excel.
Is the above comment from PSVariable documentation something I should worry about, or I can continue creating PSVariable derived classes? Is there another way of making Excel globals available to PowerShell?
Our documentation is wrong - it is a supported scenario.
Here's a bit more about the technique:
http://poshcode.org/2198
http://www.leeholmes.com/blog/2009/03/26/more-tied-variables-in-powershell/
http://www.pavleck.net/powershell-cookbook/ch03.html
Lee Holmes [MSFT]
Windows PowerShell Development
Obviously in your second example, where you are not deriving from PSVariable, you couldn't expect the $ActiveCell variable to change with the value of the ActiveCell property since you're capturing its value just once.
I don't believe deriving from PSVariable is a supported scenario, but it does work and I've done it to add variables such as $Now and $Today.
It might be a better idea to just expose an $Application variable to PowerShell script instead of the various properties of the Application object. The upside to this is that you wouldn't need to create a bunch of automatic variables and PowerShell scripts could access anything the Application object has to offer by using $Application.ActiveCell. The other benefit is that it doesn't need to be an automatic variable at all because the Application object reference will never change.
Having said all that, I've included a subclass of PSVariable that I use from time to time which takes a ScriptBlock for the getter and setter. This lets me define automatic variables from PowerShell without needing a separate derived class for each one.
using System;
using System.Management.Automation;
namespace Einstein.PowerShell
{
public sealed class DynamicVariable : PSVariable
{
#region Constructors
/// <summary>
/// </summary>
public DynamicVariable(string name, ScriptBlock onGet)
: this(name, onGet, null)
{
}
/// <summary>
/// </summary>
public DynamicVariable(string name, ScriptBlock onGet, ScriptBlock onSet)
: base(name, null, ScopedItemOptions.AllScope)
{
OnGet = onGet;
OnSet = onSet;
}
#endregion
#region Properties
/// <summary>
/// The ScriptBlock that runs to get the value of the variable.
/// </summary>
private ScriptBlock OnGet
{
get;
set;
}
/// <summary>
/// The ScriptBlock that runs to get the value of the variable.
/// </summary>
private ScriptBlock OnSet
{
get;
set;
}
/// <summary>
/// Gets or sets the underlying value of the variable.
/// </summary>
public override object Value
{
get
{
if (OnGet == null) {
return null;
}
return OnGet.Invoke();
}
set
{
if (OnSet == null) {
throw new InvalidOperationException("The variable is read-only.");
}
OnSet.Invoke(value);
}
}
#endregion
}
}