AutoMapper IObjectMapper example - automapper

In short, has anyone got one, including how to register the custom mapper.
I'm trying to map a custom IList<T> implementation and am not getting very far.

Just replace the MapperRegistry.AllMappers with a new list. Here's the default:
public static Func<IEnumerable<IObjectMapper>> AllMappers = () => new IObjectMapper[]
{
new DataReaderMapper(),
new TypeMapMapper(TypeMapObjectMapperRegistry.AllMappers()),
new StringMapper(),
new FlagsEnumMapper(),
new EnumMapper(),
new ArrayMapper(),
new EnumerableToDictionaryMapper(),
new DictionaryMapper(),
new ListSourceMapper(),
new ReadOnlyCollectionMapper(),
new CollectionMapper(),
new EnumerableMapper(),
new AssignableMapper(),
new TypeConverterMapper(),
new NullableMapper()
};
You'd take this Func, and replace it with something else, with this set of code as a starting point.
Not the prettiest thing in the world, but at least it's possible.

Related

How can I add new mapper to the already Initialized Mapper?

I want to add new maps to the Mapper created. I studied this document
http://docs.automapper.org/en/stable/Configuration.html#profile-instances
but could not understand it. The way I want is like this
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Contact, Person>();
cfg.CreateMap<Student, Class>();
etc..
});
//My other code
//My other code
cfg.CreateMap<X, Y>();
So I want to reach cfg again and use it to add new maps to existing mapper configuration. How can I add new mapper to the already Initialized Mapper?

Welding a ContentPart having a ContentField

I'm trying to Weld my custom ContentPart SitesPart containing a ContentField of type TaxonomyField but it is not working for me. When i attach this part from UI it works perfectly fine and i see the TaxonomyField in edit mode as well as in display mode.
Following is the Activating method of my ContentHandler.
protected override void Activating(ActivatingContentContext context)
{
if (context.ContentType == "Page")
{
context.Builder.Weld<SitesPart>();
}
}
I tried to go deep into the Weld function and found out that it is not able to find correct typePartDefinition. It goes inside the condition if (typePartDefinition == null) which creates an empty typePartDefinition with no existing ContentFields etc.
// obtain the type definition for the part
var typePartDefinition = _definition.Parts.FirstOrDefault(p => p.PartDefinition.Name == partName);
if (typePartDefinition == null) {
// If the content item's type definition does not define the part; use an empty type definition.
typePartDefinition =
new ContentTypePartDefinition(
new ContentPartDefinition(partName),
new SettingsDictionary());
}
I would be highly thankful for any guidance.
Oh, you are totally right, the part is welded but if there are some content fields, they are not welded. The ContentItemBuilder try to retrieve the part definition through the content type definition on which we want to add the part. So, because it's not possible, a new content part is created but with an empty collection of ContentPartFieldDefinition...
I think that the ContentItemBuilder would need to inject in its constructor and use a ContentPartDefinition or more generally an IContentDefinitionManager... But, for a quick workaround I've tried the following that works
In ContentItemBuilder.cs, replace this
public ContentItemBuilder Weld<TPart>()...
With
public ContentItemBuilder Weld<TPart>(ContentPartDefinition contentPartDefinition = null)...
And this
new ContentPartDefinition(partName),
With
contentPartDefinition ?? new ContentPartDefinition(partName),
And in you part handler, inject an IContentDefinitionManager and use this
protected override void Activating(ActivatingContentContext context) {
if (context.ContentType == "TypeTest") {
var contentPartDefinition = _contentDefinitionManager.GetPartDefinition(typeof(FruitPart).Name);
context.Builder.Weld<FruitPart>(contentPartDefinition);
}
}
Best
To attach a content part to a content type on the fly, you can use this in your handler
Filters.Add(new ActivatingFilter<YourContentPart>("YourContentType"));
There are many examples in the source code
Best

How can I add new Monotouch dialog views dynamically?

When creating views in Monotouch Dialog, one possible way is to create .cs files which hold the view information like so:
[Caption("Create user")]
[Alignment(UITextAlignment.Center)]
public RegistrationSchema CreateAccount;
But say I needed to have button added dynamically, like so:
//This is what I'd like to do, but there doesn't seem to be any support for this
_newUserSection = new Section("Create user) {
new RegistrationSchema()
};
Any ideas?
Edit My RegistrationSchema.cs file
public class RegistrationSchema
{
[Section("Fill out the form")]
[Caption("E-mail")]
[Entry(KeyboardType=UIKeyboardType.EmailAddress)]
public string Email;
//more stuff here
}
// Create a new section
var section = new Section("A section");
// Create a new element
var elem = new StringElement("String Element")
// Add element to section
section.Add(elem);
// Add section to root.
Root.Add(section);
// Refresh
Root.ReloadData();
All well documented here https://github.com/migueldeicaza/MonoTouch.Dialog and in the Xamarin tutorials, like there http://blog.xamarin.com/2012/02/10/easily-create-ios-user-interfaces-with-monotouch-dialog/
To push a new controller, use a RootElement:
var newRoot = RootElement("Another root", new ThisWillBePushedController());
root.Add(newRoot);
Tapping the newRoot will push the ThisWillBePushedController().
Note that you'll have to override MonoTouch.DialogViewController and call the base c'tor passing TRUE for the last argument "pushing" if you're using a UINavigationController.

foreach inside xdocument.add

I have a class that has a dictionary field. I want to loop through every item of this class and create an xml document but inside this loop I want to loop through this dictionary properties and add the key values pairs.
I am looking for something that will do the following
foreach(Book bk in query)
{
ReturnData.Descendants("Books")
.FirstOrDefault().Add(new XElement("Book",
new XElement("Name", bk.BookName),
new XElement("Measure", bk.Measure,
.foreach(KeyValuePair<string, double> measure in bk.NewMeasures)
{
new XElement(measure.Key,measure.Value)
},
new XElement("Value", bk.PreviousValue))));
}
Return data already contains some XML, this is why I am adding to the Books descendants. It may already have other roots such as videos, games etc.
Appreciate any thoughts on this.
First of all, I would query for the first book outside the loop:
var book = ReturnData.Descendants("Books").FirstOrDefault();
And then use it within the loop:
foreach(var b in query)
{
book.Add(new XElement("Book",
new XElement("Name", b.Name),
new XElement("Measure", b.Measure,
from m in b.NewMeasures select new XElement(m.Key, m.Value)),
new XElement("Value", b.Value)));
}

Using FindView in Orchard

I'm trying to use:
var viewEngineResult = ViewEngines.Engines.FindView(ControllerContext, myViewName, null);
as part of a process to render the contents of a view to send nice formatted emails. I'm using it inside an Orchard Controller. I have used similar code outside of Orchard in an MVC project and it works fine.
However in Orchard running this code fails to find the view I'm looking for and returns a view engine result that has searched 0 locations.
viewEngineResult has the following values after it is called:
SearchedLocations: Count = 0,
View: null,
ViewEngine: null
Is there a reason this doesn't work in Orchard and is there a way to make it work?
This answer is based on the advise given me by Bertrand, but I wanted to bring it together with what I'd discovered.
To be able to use FindPartialView I needed to inject an instance of IViewEngineProvider into my controller.
I then used the following code to resolve and render a view:
private String RenderView(String viewName, object model)
{
var paths = new List<string>(); // This can just be an empty list and it still finds it.
var viewEngine = _viewEngineProvider.CreateModulesViewEngine(new CreateModulesViewEngineParams {VirtualPaths = paths});
var viewResult = viewEngine.FindPartialView(ControllerContext, viewName, false);
if (viewResult.View == null) {
throw new Exception("Couldn't find view " + viewName);
}
var viewData = new ViewDataDictionary {Model = model};
using (var sw = new StringWriter())
{
var viewContext = new ViewContext(ControllerContext, viewResult.View, viewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
I think you'll want to take a close look at Orchard.Framework/Mvc/ViewEngines, in particular IViewEngineProvider and ThemeAwareViewEngine. There's a lot more going on when in Orchard, such as themes, multi-tenancy, and a richer environment in general that may be needed to make this work.
What's likely happening here is that the view engines don't have enough information to resolve a view and thus opt out of the chain. You might want to put a breakpoint into ThemeAwareViewEngine.FindView, and then inspect the private dependency fields of that class. I wouldn't be surprised if they were null, because getting to FindView through statics will probably not allow dependency injection to do its stuff properly.
Then again I'm just guessing.

Resources