I'm trying to find an IOC container that will allow me to have mapping data for a field stored in a database and resolve the interface or object that needs resolved via a string value pulled from the database.
Most of the examples I have seen are using interfaces hard coded in code, I want the interface that needs to be resolved to be dynamic.
This is what I usually see:
var taskController = container.Resolve<ITaskController>();
This is what I would like to see:
var strTaskController = "ITaskController";
var taskController = container.Resolve(strTaskController);
I'm sure I could look through the documentation for all the IOC containers but I am hoping this is an easy question for someone with more IOC experience.
Using Unity you can do what you're looking for. Basically, if you know the full type name, you can do this first:
var type = Type.GetType("Fully.Qualified.Type.Name");
var resolvedInstance = container.Resolve(type);
EDIT: Based on the comment, here's another approach:
string typeName = "MyTypeName";
var type = container.Registrations.FirstOrDefault(r => r.RegisteredType.Name == typeName);
if(type != null)
{
var resolvedInstance = container.Resolve(type.RegisteredType);
}
I think this is the answer I am going with..
Managed Extensibility Framework
http://msdn.microsoft.com/en-us/library/dd460648.aspx
Got to love it when you find a new framework to find the exact solution to your problem.
You can use the IOC container from the Castle project.
Related
I want to be able to do something like the following:
var book = new Book();
book.LoadByPrimaryKey(id); //returns bool
The issue I am coming across is I can't figure out if there is a simple way to load data into an object generated using Entity Framework. I understand how to grab the information needed to fill the object, but is there a simple way to fill out all the properties of an object without explicitly going through each property and setting it to the desired value? In C# I cannot simply type:
this = db.Books.Single(d => d.BookId == id);
I instead have to explicitly set each property:
var book = db.Books.Single(d => d.BookId == id);
this.Title = book.Title;
this.PageCount = book.PageCount;
...
Is there a way around doing this when wanting to load up an object? Maybe something with a DbDataReader? I have used the data reader to load DataTables, but can't figure out how to use them to populate an object. Maybe I'm over thinking it.
When you need to copy all of the properties from one object to another you can
Just write the code (typing practice)
Generate the code using a T4 Template
Use Reflection
Use Automapper
As David Browne previously answered:
Just write the code (typing practice)
Generate the code using a T4 Template
Use Reflection
Use Automapper
The answer he gave you is correct. But I'm want to extend it and explain why.
First, let put some concept here. When we go further in programming techniques, sometimes, the working answer, it not enough. Although what you trying to do is a valid solution for the problem, there is some issue with it.
The is a concept that is called S.O.L.I.D. The first letter (S) stands for Single Responsibility Principle. This means that one object should have only one responsibility.
The problem in your approach is you are putting multiple responsibilities in a single object:
Hold/Transport information about a book.
Load from a remote server (in this case a DataBase) information about a book.
You probably googled this issue before post here, and I suspect you found nothing useful. Now the reason you found nothing is because this is a bad approach, it goes against the SOLID concepts, and it breaks several interation with possible Design Patterns. So this is why you probably found nothing, there is no previous conceived tool of workaround to this problem, because this is a discouraged approach, so no one, with a little understand of program techniques, will help you.
Therefore, we go back to the answer that David Browne gave you. To use Automapper (the simplest of the suggestions). You need to change your approach. Consider to separate each responsibility in a different class:
class BookDA // DAO = data access
{
private MyDbConnection db;
public BookTO Get()
{
var book = db.Books.Single(d => d.BookId == id);
return book;
}
}
class BookTO // TO = transport object
{
public string Name { get; set; }
}
In the code above each responsibility is associated with a different class. This answer became too long but I hope it helps.
I'm apologizing if I'm using the wrong terminology here. I'm still very much in the ORM world, but I've been playing around with MongoDb and really love what I see. One of the things I'm not liking is this:
var books = bookRepository.GetCollection<BsonDocument>("books");
And
foreach (var book in books.FindAllAs<Book>())
{
Console.WriteLine("Author: {0}, Title: {1}", book.Author, book.Title);
}
I've found several tutorials on wrapping NoRM in a session but I can't figure out how to do it using the CSharp Drivers (the ones that Mongodb recommends / has on their github page).
What I'd really like to do is something like this for the first example:
var bookRepository = MongoRepository<Book>(); // probably should use IoC to resolve this
and
foreach (var book in books.FindAll())
Voila! I'm probably not the first person to want this, using strings everywhere seems a bit nutty, though I will grant that the tutorial is just an example. Is there a "best practices" example to setting this all up in such a manner?
Edit: Please let me know if this is crazy talk and not how to do things in Mongo, again this is my first test project.
Here is snippet from my project:
public static MongoCollection<T> GetCollection<T>(string collectionName = null)
{
if (string.IsNullOrWhiteSpace(collectionName))
{
Type g = typeof (T);
collectionName = g.Name;
}
return MongoServer.Create(Config.MongoConnectionString).GetDatabase(Config.Database).GetCollection<T>(collectionName);
}
Now I dont need to specify a collection name as a string unless I want to override it:
var collection = GetCollection<MyEntity>();
or
var collection = GetCollection<MyEntity>("SomeOtherCOllection");
You can use some inflection utility\library to pluralize your collection names if you want.
Also, you dont need to specify the type in your Find methods if you specified the type when instantiating a collection class, like I have above.
For example, this is how I do it:
MongoCursor<MyEntity> results = collection.FindAll();
or
MongoCursor<MyEntity> results = collection.Find(query);
Something along those lines:
builder.RegisterType<MyType>().As<IType>();
builder.RegisterType<MyType2>().As<IType>();
builder.DeRegisterType<MyType>().As<IType>()
var container = builder.Build();
var types = container.Resolve<IEnumerable<IType>>();
Assert.IsTrue(types.Count == 1);
Assert.IsTrue(types[0].GetType == typeof(MyType2));
Scenario: I go through bunch of assemblies and as I go I register types but I want to
make sure that I have only one implementation of a given type. I need to do this before I create the container. I could track that on my own but it would be nice if Autofac could help me a bit.
This cannot be done directly using the ContainerBuilder, unless you start over with a new one. Mind you, having first built a container you should be able to construct a new container filtering away unwanted types and reusing the registrations from the first container. Like this:
...
var container = builder.Build();
builder = new ContainerBuilder();
var components = container.ComponentRegistry.Registrations
.Where(cr => cr.Activator.LimitType != typeof(LifetimeScope))
.Where(cr => cr.Activator.LimitType != typeof(MyType));
foreach (var c in components)
{
builder.RegisterComponent(c);
}
foreach (var source in container.ComponentRegistry.Sources)
{
cb.RegisterSource(source);
}
container = builder.Build();
This is hardly very elegant but it works. Now, if you could elaborate on why you want to do this, perhaps there is a better way.
Peter L.'s probably got the most straightforward option.
To get around the problem altogether, can you modify the way you're discovering components to filter them in advance of registration? It does seem like there must be an approach that gets around this... It also might be a challenge further down the track to work out which components to keep vs. which to remove.
A more involved approach is to override IEnumerable support to filter out the the things you don't want. I.e. copy and modify this code to create a FilteredCollectionSource that excludes the components you don't want.
var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService);
would become:
var elements = c.ComponentRegistry.RegistrationsFor(elementTypeService)
.Where(reg => /* not a duplicate */);
If you add your FilteredCollectionSource to the builder using RegisterSource() it will should get used instead of the built-in one.
In my current project I'm currently trying to replace the Windsor IoC in favour of structure map (2.6.1). But having a bit of problem registering some generic types. How would I register IFilterConverter<T> to use FilterConverter<SomeSpecificType>. I've tried ConnectImplementationsToTypesClosing(IFilterConverter) but from what I've read (Jimmy Bogard's article) I would need a concrete type defined like so:- SomeConcreteType : IFilterConverter<SomeSpecificType> for that to work and I don't have that.
So to reiterate if I have a type that takes a constructor argument IFilterConverter<SomeSpecificType>, I want structure map to provide me with FilterConverter<SomeSpecificType>.
With Windsor I was using the XML config option (which I want to get away from) But all I did was just set up the configuration like so:
<component id="IFilterConverter" service="SomeNamespace.IFilterConverter`1, SomeNamespace" type="SomeNamespace.FilterConverter`1, SomeNamespace" lifestyle="PerWebRequest">
How do I do the equivalent in SM (using code, not XML config files)
Thanks
I think this should do it.
_container = new Container();
_container.Configure(x =>
{
x.For(typeof (IFilterConverter<>)).Use(typeof (FilterConverter<>));
});
I've created an ISearchable interface that I've Typed so that I can retrieve an IEnumerable of T for the results.
I have a number of services that implement ISearchable for different domain objects ...
Container.RegisterType<ISearchable<Animal>, AnimalService>();
Container.RegisterType<ISearchable<Fish>, FishService>();
I want to resolve (through Unity) an ISearchable based on the type, but am struggling to get it to work ...
The following dosn't compile but will hopefully give an idea of what I'm trying to achieve.
Type t = typeof(Animal);
var searchProvider = _container.Resolve<ISearchable<t>>();
Any helped gratefully received!
Thanks,
Andy
Finally sorted it, hopefully it'll be of help to someone else!
var type = filter.GetType();
var genericType = typeof(ISearchable<>).MakeGenericType(type);
var searchProvider = _unityContainer.Resolve(genericType);
Why not register your types by name and resolve that way?
Container.RegisterType<ITelescopeView, TelescopeView>("type1");
Container.RegisterType<ITelescopeView, TelescopeView2>("type2");
Container.Resolve(ITelescopeView, "type1");
If you want your names can simply be the type's full name or you could use something else. Dmitri's approach will work too. But this might result in clearer code.
How about...
var sp = container.Resolve(
Type.GetType("ISearchable`1[" + yourGenericTypeHere + "]"));