MvvmCross: Turn off MvxTrace timestamps (PrependWithTime) - mvvmcross

Looking for recommendations on how to override the default implementation of MvxTrace to disable the default behaviour of appending the time since application launch aka PrependWithTime:
https://github.com/MvvmCross/MvvmCross/blob/v3.1/CrossCore/Cirrious.CrossCore/Platform/MvxTrace.cs#L152
private static string PrependWithTime(string input)
{
var timeIntoApp = (DateTime.UtcNow - WhenTraceStartedUtc).TotalSeconds;
return string.Format("{0,6:0.00} {1}", timeIntoApp, input);
}

Looking at the code, I'd guess you can't easily override this behaviour.
If it's just text formatting you want to change, then you could remove the timestamps again afterwards in a custom IMvxTrace implementation injected during Setup.
However, if you wanted more customisation here, then you'd need to make some sort of change to Mvx - which you could do via a Feature Request or Pull Request in http://github.com/mvvmcross/mvvmcross/issues

Related

How to get settings in middleware?

I'm sure this has got to be a duplicate, but I've been searching way too long and still can't find the answer.
I want to access configuration options (from a json file, although I don't think the source matters in regard to my question) from here:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Run(async context =>
{
// Get my config values here and do something with them
await Task.CompletedTask;
});
}
I could use var x = Config.GetValue<string>("AppSettings:MySetting:0"); but because it's a list I would have to create a loop and retrieve values until I get a null value and all that so I would rather do the IOptions thing so it loads it in a strongly typed class for me. I have this code in ConfigureServices:
services.AddOptions();
services.Configure<AppSettings>(Config.GetSection("AppSettings"));
but I just don't know how to get at the object that's registered there from within the Configure method.
I also tried inspecting the value of Config.GetSection("AppSettings") while debugging and found that under the json provider I could see my settings. However, while that's available in the inspector, I can't see how I can directly access my list. That is, I can access my list one value at a time using GetValue() but I can't just access the whole list as one value.
As often seems to happen, I finally figured out what I was looking for right after making a post here. Basically, I don't need IOptions or anything else having to do with DI for my scenario. I just needed to use .Bind() to bind the settings to an instance of my class:
AppSettings a = new AppSettings();
Config.GetSection("AppSettings").Bind(a);

How to get back MDC "inheritance" with modern logback?

After going back to an older project and getting around to update its dependencies I had to realize that logback does not anymore propagate MDCs to children since version 1.1.5: https://github.com/qos-ch/logback/commit/aa7d584ecdb1638bfc4c7223f4a5ff92d5ee6273
This change makes most of the logs nigh useless.
While I can understand the arguments given in the linked issues, I can not understand why this change could not have been made in a more backwards compatible manner (as is generally usual in java..).
Q: What is the now correct way to achieve the same behaviour other than having to subclass everything from Runnables to Threads?
I see no straightforward way to change this back. Two alternatives that come to mind are:
Way #1: Wrap all Runnables
Introduce an abstract class that will copy MDC from the original Thread to a new Thread and use it instead of Runnable
public abstract class MdcAwareRunnable implements Runnable
{
private Map<String, String> originalMdc;
public MdcAwareRunnable()
{
this.originalMdc = MDC.getCopyOfContextMap();
}
#Override
public void run()
{
MDC.setContextMap(originalMdc);
runImpl();
}
protected abstract void runImpl();
/**
* In case some Runnable comes from external API and we can't change that code we can wrap it anyway.
*/
public static MdcAwareRunnable wrap(Runnable runnable)
{
return new MdcAwareRunnable()
{
#Override
protected void runImpl()
{
runnable.run();
}
};
}
}
If some Runnable comes from an external API that you can't change that code, use wrap helper method.
Drawback: need to analyze and change whole code.
Way #2: Mess with slf4j internals
Resurrect the original LogbackMDCAdapter implementation that uses InheritableThreadLocal from before that commit and put it somewhere in your code under some other name. Then somewhere around startup use reflection to override MDC.mdcAdapter property with and instance of that custom implementation. This is obviously a dirty hack but it saves a lot of troubles comparing to #1.
Note: for performance reasons it makes to inherit your resurrected version from existing LogbackMDCAdapter and just override all the methods with old implementation. See LoggingEvent.java and LogbackMDCAdapter.getPropertyMap internal method for some details.
Way #3: Mess with logback jar (even stranger alternative)
This sounds to me as a quite bad plan but for completness here it is.
Again resurrect the original LogbackMDCAdapter but this time don't rename, compile it and override that .class file inside logback.jar.
Or resurrect the original LogbackMDCAdapter with renaming, remove .class file for org.slf4j.impl.StaticMDCBinder from logback.jar and add your own class that will return resurrected version of LogbackMDCAdapter either to logback.jar or to your code. MDC seems to be bound to that class by name to create an implementation of MDCAdapter to use.
Or you can achieve similar result by using custom ClassLoader that would map org.slf4j.impl.StaticMDCBinder to your class instead of the one inside logback.jar. Note: this is probably impossible to achieve inside a Web-container that will add its own custom ClassLoaders.
Way 4: Misuse TurboFilter
ch.qos.logback.classic.Logger passes the logging event to a filter before passing it along to the appenders.
Way 5: Modify log Encoder / provider
Although this would mean the logging event is not updated, but the log output will be.

How to implement PropertyDefiner for logback to access multiple properties

I would like to define some properties in my logback.xml config file and saw that by implementing the PropertyDefiner was a great way to set properties in a customizable way.
After starting to implement it I began to wonder how to access the value of the name attribute of the element within the tag. I'm not seeing anyway to do this and I'm scratching my head. Would this PropertyDefiner really make you create a new implementation for every single property? Why not just hard code it? I didn't see much discussion about this out on the web.
I hope I'm just not seeing it and that the brains of stackoverflow can help me out. Does anyone know how to do this? Thanks!
I found this discussion: essentially the same question is asked, but no answer was returned.
fyi: I want to customize how I get my properties because I am pulling it from a database. I have a helper class which pulls the properties in on server startup. These properties vary based on environment (dev, test, prod, etc.)
As of logback version 1.0.6, the value of the name attribute cannot be accessed directly. However, nothing prevents you from passing the value of the name attribute in a property of your choice. Example:
<define name="rootLevel" class="Your.PropertyDefiner">
<myKey>rootLevel</myKey>
</define>
where myKey is a property of Your.PropertyDefiner. For example:
class Your.PropertyDefiner implements PropertyDefiner {
String myKey;
public void setMyKey(String k) {
this.myKey= k;
}
public String getPropertyValue() {
return ...
}
}
Joran, logback's configuration framework, takes care of the wiring. Joran will inject the value of the myKey element into the myKey property of Your.PropertyDefiner. If you are curious about the technical details, see the documentation on implicit actions and implicit actions in practice.

How to map the PHP DateTime class to ActionScript / Flex Date class using Zend Framework AMF

Background
Okay I'm one of those guys who NEVER asks questions and who can usually find what I need from existing questions or forums....but alas I have spent the last few days trying to figure this one out and have come up with very little existing information.
I am using Flash Builder 4.6 for PHP Premium to build a Flex application that uses the PHP Zend Frameworks's AMF capabilities to map classes from PHP to Flex and to use them as objects to send back and forth instead of using XML or JSON. Right now I am doing it all on a single local machine for ease.
Issue
I am not having trouble mapping my own custom PHP classes into ActionScript/Flex classes but I cannot for the life of me manage to map a DateTime PHP class into an ActionScript Date class. I have read elsewhere that it automatically maps DateTime objects to Date objects but I have never gotten it to work.
Strangely though, I can get it to work if I replace all instances of, in my case, valueObjects.DateTime (the auto-generated ActionScript class) to Date in the _Super_Foo.as class that has the DateTime property. This basically forces Flex to interpret the data of that property as a Date. However, since all the _Super_XXX.as files are files that autogenerated by Flex, it gets rewritten any time I refresh or edit ANY PHP service that Flex is linking to in Flash Builder.
Remarks
I could of course do this the quick and dirty way by keeping the variable as a string (it's coming from MySQL in a DateTime field) and then just create some functions to convert it to a Date object on the client side but I need a more permanent and stable solution.
Example:
<?php
class Foo {
public $id; // int
public $name; // string
public $date; // DateTime
public $bar; // custom object
}
?>
should go to --->
package {
class Foo {
public var id:int;
public var name:String;
public var date:Date; // native class
public var bar:Bar;
}
}
but I am getting
package {
class Foo {
public var id:int;
public var name:String;
public var date:DateTime; // custom class
public var bar:Bar;
}
}
I have tried things such as the following:
in the gateway.php file
$server->setClassMap("Date", "DateTime");
using the Zend_Date object instead
$foo->date = new Zend_Date($blah);
and after trying to map it as well explicitly
$server->setClassMap("Date", "Zend_Date");
the change I currently have working in the _Super_Foo.as file (which gets written over frequently)
private var _internal_date : valueObjects.DateTime; // custom object
to
private var _internal_date : Date; // native object
I just need it to do this automatically like I have read it should.
Well I have to admit, that I usually use BlazeDS on Java and not Zend, but I have had similar problems in transfering Calendar objects (I wanted to prevent loosing the timezone data). For This BlazeDS supported so-called PropertyProxys, which are components that allow to takeover the serialization/deserialization process for certain types.
I would assume that ZEND would support a similar thing. So another option would actually be to make Zend zupport the full Flex type. I have searched a little and it seems that the entire terminology is different in Zend, but I think this stackoverflow article should explain it a little: Zend AMF custom dispatcher
Chris
In my experience, Zend Framework has taught me that it offers many features but many times they don't work exactly how you'd expect. For example:
Recently I was working with a bug in "digitalus-cms" (A blog-like framework built on top of ZF) that it couldn't post new articles with a hyphen in their title name. I tracked it down to Zend_Form_Element::filterName. It uses a regular expression that matches any character that falls into the category of: [^a-zA-Z0-9_\x7f-\xff] then removes it. This ends up removing hyphens from the names of form elements which wound up being the cause of the bug.
If Zend_Amf or Zend_Date doesn't work the way you want it to, find a workaround such as passing a unix timestamp number around so everything works the way it should. Then afterwards, you can write a class to extend off one of Zend's classes. Zend Framework is meant to be extended upon, that's the way the framework was built so you can fix issues like these on your own to get the framework to behave how you want it to. That's the whole point of wrappers. Go ahead, create some of your own wrapper classes and toss in some methods to interact with ZF so you can fine-tune everything.
As far as finding the cause of your issue, all I can tell you is keep on debugging and isolating code so you know what you are passing flex, and how flex responses to that. After you play around with it enough, I'm sure you'll find the culprit.
AmfPHP automatically maps it. http://www.silexlabs.org/amfphp/

Registering derived classes with reflection, good or evil?

As we all know, when we derive a class and use polymorphism, someone, somewhere needs to know what class to instanciate. We can use factories, a big switch statement, if-else-if, etc. I just learnt from Bill K this is called Dependency Injection.
My Question: Is it good practice to use reflection and attributes as the dependency injection mechanism? That way, the list gets populated dynamically as we add new types.
Here is an example. Please no comment about how loading images can be done other ways, we know.
Suppose we have the following IImageFileFormat interface:
public interface IImageFileFormat
{
string[] SupportedFormats { get; };
Image Load(string fileName);
void Save(Image image, string fileName);
}
Different classes will implement this interface:
[FileFormat]
public class BmpFileFormat : IImageFileFormat { ... }
[FileFormat]
public class JpegFileFormat : IImageFileFormat { ... }
When a file needs to be loaded or saved, a manager needs to iterate through all known loader and call the Load()/Save() from the appropriate instance depending on their SupportedExtensions.
class ImageLoader
{
public Image Load(string fileName)
{
return FindFormat(fileName).Load(fileName);
}
public void Save(Image image, string fileName)
{
FindFormat(fileName).Save(image, fileName);
}
IImageFileFormat FindFormat(string fileName)
{
string extension = Path.GetExtension(fileName);
return formats.First(f => f.SupportedExtensions.Contains(extension));
}
private List<IImageFileFormat> formats;
}
I guess the important point here is whether the list of available loader (formats) should be populated by hand or using reflection.
By hand:
public ImageLoader()
{
formats = new List<IImageFileFormat>();
formats.Add(new BmpFileFormat());
formats.Add(new JpegFileFormat());
}
By reflection:
public ImageLoader()
{
formats = new List<IImageFileFormat>();
foreach(Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if(type.GetCustomAttributes(typeof(FileFormatAttribute), false).Length > 0)
{
formats.Add(Activator.CreateInstance(type))
}
}
}
I sometimes use the later and it never occured to me that it could be a very bad idea. Yes, adding new classes is easy, but the mechanic registering those same classes is harder to grasp and therefore maintain than a simple coded-by-hand list.
Please discuss.
My personal preference is neither - when there is a mapping of classes to some arbitrary string, a configuration file is the place to do it IMHO. This way, you never need to modify the code - especially if you use a dynamic loading mechanism to add new dynamic libraries.
In general, I always prefer some method that allows me to write code once as much as possible - both your methods require altering already-written/built/deployed code (since your reflection route makes no provision for adding file format loaders in new DLLs).
Edit by Coincoin:
Reflection approach could be effectively combined with configuration files to locate the implmentations to be injected.
The type could be declared explicitely in the config file using canonical names, similar to MSBuild <UsingTask>
The config could locate the assemblies, but then we have to inject all matching types, ala Microsoft Visual Studio Packages.
Any other mechanism to match a value or set of condition to the needed type.
My vote is that the reflection method is nicer. With that method, adding a new file format only modifies one part of the code - the place where you define the class to handle the file format. Without reflection, you'll have to remember to modify the other class, the ImageLoader, as well
Isn't this pretty much what the Dependency Injection pattern is all about?
If you can isolate the dependencies then the mechanics will almost certainly be reflection based, but it will be configuration file driven so the messiness of the reflection can be pretty well encapsulated and isolated.
I believe with DI you simply say I need an object of type <interface> with some other parameters, and the DI system returns an object to you that satisfies your conditions.
This goes together with IoC (Inversion of Control) where the object being supplied may need something else, so that other thing is automatically created and installed into your object (being created by DI) before it's returned to the user.
I know this borders on the "no comment about loading images other ways", but why not just flip your dependencies -- rather than have ImageLoader depend on ImageFileFormats, have each IImageFileFormat depend on an ImageLoader? You'll gain a few things out of this:
Each time you add a new IImageFileFormat, you won't need to make any changes anywhere else (and you won't have to use reflection, either)
If you take it one step further and abstract ImageLoader, you can mock it in Unit Tests, making testing the concrete implementations of each IImageFileFormat that much easier
In vb.net, if all the image loaders will be in the same assembly, one could use partial classes and events to achieve the desired effect (have a class whose purpose is to fire an event when the image loaders should register themselves; each file containing image loaders can have use a "partial class" to add another event handler to that class); C# doesn't have a direct equivalent to vb.net's WithEvents syntax, but I suspect partial classes are a limited mechanism for achieving the same thing.