10 Aug
2010

Verbesserte Audiotechnik bei mir im Hause

Ich habe ja heute meinen ersten offiziellen Screencast aufgenommen, zu Ehren der Erwerbs von diverser Hardware zur Ton-Aufzeichnung. Eine Anschaffung eines richtigen Mikrofons zur Aufnahme von Ton hatte ich schon lange vor, doch was kauft man, in was investiert man und man möchte vielleicht nicht soviel zum spielen ausgeben.

Da kam mir der Blog-Artikel von James Kovacs gerade recht in dem er beschreibt was er nutzt. Er nutzt das Audio-Technica AT2020. Dies gibt es hier in Deutschland für so um 99€. In Anlehnung seines Blogs mit Qualitätsvergleich mache ich dies nun auch. Von der Technik habe ich keine Ahnung, sie muss funktionieren. Technisches kann man bei James nachlesen.

Bestellung

Nun habe ich mich am Sonntag dann in den Online Musikladen meines Vertrauens gestürzt und ein wenig gestöbert was ich denn für mich so brauchen könnte. Da kam schon was zusammen, natürlich erstmal das Mikrofon. Dies gab es als USB und als XLR Ausführung. USB hätte den Vorteil ich kann es direkt am Rechner anschließen, der Nachteil ist ich kann es nur am Rechner anschließen. Dies ist etwas was ich nicht möchte da ich es auch woanders verwenden kann (ich denke da an Podcasts, Interviews, auch mal Unterwegs) und dann vielleicht zu eingeschränkt bin bei möglicher weiterer Hardware (z.B. Mehrspurrekorder).

Also kommt nur die XLR Ausführung in Frage, die braucht jedoch 48V Phantomspeisung. Dafür gibt es mehrere Lösungen, Vorverstärker, USB A/B Wandler. Ich habe mich für der Einfachheithalber für ein Set entschieden wo so ein Microport XLR/USB Wandler dabei war. Keine Ahnung ob der was taugt, aber ist im Set also wird’s schon passen dachte ich mir.

Dazu kam dann noch ein Mikrofonhalter, eine Spinne die das Mikro von schlägen auf dem Tisch entkoppelt, ein Tischarm für’s Mikrofon und ein Popp-Schutz.

Lieferung

Heute brauchte der UPS Mensch das Paket mit allen Inhalten vorbei, bis auf die Spinne funktioniert alles, die habe ich wohl eine Nummer zu eng gekauft, ich bekomme das Mikrofon da nicht rein.

Entäuschung

Nachdem ich das dann alles in Betrieb genommen hatte habe ich den Screencast aufgenommen. Und es wurde zurecht eine nicht ganz so gute Tonqualität vernommen, als ob ich zu weit wegwäre. Ich war schon was unzufrieden, da ganze Geld und dann sowas. Somit schob ich es auf die Software. Aber die war nicht an allem Schuld.

Ganz wichtig bei so einem Semi-Pro mit Nierencharakteristik ist das man es auch an die richtige Stelle beschallt. Dies habe nich nicht gemacht, ich habe oben hineingesprochen, was für dieses nicht ganz so gut war. Es gibt welche da funktioniert dies.

Ok, ich verspreche nun immer seitlich reinzusprechen, aber auch nur von vorne.

Alles wieder gut

Nachdem mir nun bekannt es von welcher Stelle ich das Mikrofon zu beschallen habe ich nun auch den Qualitätsvergleich gemacht. Mir stehen nun 3 externe Mikrofone zu Verfügung.

  1. Microsoft WebCam LifeCam VX-7000
  2. Logitech Premium Notebook Headset USB
  3. Audio-Technica AT220

Mit dem Headset war ich so zufrieden, es macht seinen Job war nicht teuer und für LiveMeetings und so hat es gereicht. War das gerade nicht greifbar wurde auf das Mikro der WebCam zurückgriefen (Messenger & Skype). Ich musste mich ja nicht hören.

Zur Test Aufnahme habe ich also das Headset aufgezogen, und mich so vor das neue Mikro positioniert wie ich auch am Rechner arbeite und in Standard WebCam abstand bin. Dann habe ich die Pegel aller Mikrofone auf einen ähnlichen Stand gebracht um eine gleiche Lautstärke zu haben.

Mit der Software MixPad (Mehrspur Aufnahme) habe ich dann in einem Take alle drei Mikrofone im Kasten gehabt. Somit gibt es keine Betonungsunterschiede.

Hier nun kleine Miniplayer zum abhören. Das Getöse im Hintergrund ist wohl die Dockingstation, kommt mir hier im Betrieb nicht SOO laut vor. Aber heute ist es hier auch was wärmer. Bis auf die Umwandlung in MP3 wurde die Aufnahme nicht nachbearbeitet.

Microsoft WebCam LifeCam VX 7000

Logitech Premium Notebook Headset USB

Audio-Technica AT2020

Und alle drei zusammen

Ein Urteil kann sich nun jeder selbst bilden, entäuscht bin ich jedenfalls nicht mehr. Zumal durch die Nierencharakteristik die Hintergrundgeräusche gut gefiltert werden.

Für den XLR/USB Adapter braucht man keine Treiber (Windows7/Vista), auch bietet er auch noch einen Kopfhörer-Anschluss an den der Rechner die Soundausgabe schicken kann.


dieser Eintrag ist mir etwas Wert
 
10 Aug
2010

.resharper-Dateien–einchecken oder nicht?

Mir ist aufgefallen das in vielen Open-Source Projekte die .resharper Dateien nicht ins Quelltext-Repository aufgenommen werden. Ich bin der Meinung dies ist nicht gut, und hat auch seinen sinn. Dazu habe ich mal kurz – 3:30m - einen Screencast produziert.

Nunja, auch um mal Camtasia und mein neues Mikrofon mal zu testen Winking smile Es gibt noch Potential zur Verbesserung, wie ich gemerkt habe. Aber es ist ein Anfang.

Also, *.resharper Dateien mit  ins Repository aufnehmen, aber nicht die *.user (.resharper.user) Dateien,

Technorati Tags: ,

dieser Eintrag ist mir etwas Wert
 
07 Aug
2010

ASP.NET MVC Action und die Database Connection, nun richtig

Bei ASP.NET MVC ist es Best Practice wenn man für den Datenbank Zugriff eine Transaction beim Start der Action öffnet und zum Ende wieder schließt.

Ich habe die eine oder andere “Lösung” dazu gesehen, die sich jedoch meist in den Request-LifeCycle der Application einklinken und somit “irgendwie” außerhalb der MVC Konzeptes sind und somit auch beim Zugriff auf andere Seiten oder gar statischen Resourcen auch Connection/Transactionen öffnen. Auch ich nutzte dies … aber nun nicht mehr.

Die beste Lösung (jedenfalls aus meiner Sicht) ist ein eigener IActionInvoker der diese Aufgabe übernimm,. damit ist auch exakt den Gültigkeitsbereich der Transaktion definiert.

public interface IActionInvoker
{
    bool InvokeAction(ControllerContext controllerContext, string actionName);
}

In ASP.NET MVC ist es ein ActionInvoker der dafür sorgt dass die Action und das ActionResult so verarbeitet werden wie wir es vom Framework kennen. Die Standardimplementierung ist der ControllerActionInvoker. Der Controller selbst übernimmt die Erstellung  des IActionInvoker und zwar über die Methode CreateActionInvoker(). Diese ist virtuell und kann somit angepasst werden.

    protected virtual IActionInvoker CreateActionInvoker()
    {
      return new ControllerActionInvoker();
    }
Somit zu meiner Lösung. Ich habe einen IActionInvoker implementiert, der dafür sorge trägt dass der Aufruf der Action in in einer Datenbank-Transaction abläuft.

public class TransactionalActionInvoker : IActionInvoker
{
    private readonly IDatabaseTransaction transaction;
    private readonly IActionInvoker baseActionInvoker;

    public TransactionalActionInvoker(IDatabaseTransaction transaction,
                                        IActionInvoker baseActionInvoker)
    {
        this.transaction = transaction;
        this.baseActionInvoker = baseActionInvoker;
    }

    public bool InvokeAction(ControllerContext controllerContext, string actionName)
    {
        bool result;
        try
        {
            transaction.BeginTransaction();
            result = baseActionInvoker.InvokeAction(controllerContext, actionName);
        }
        catch (Exception)
        {
            transaction.ExceptionWhileTransaction();
            throw;
        }
        finally
        {
            transaction.EndTransaction();
        }
        return result;
    }
}
Als Abhängigkeiten drücke ich dem TransactionActionInvoker den eigentlichen IActionInvoker rein sowie eine IDatabaseTransaction zum Management des Transaktion. Ich gehe diesen Weg und leite nicht von ControllerActionInvoker ab damit beliebige Implementierungen von vorhandenen ActionInvokern verwendet werden können.

IDatabaseConnection ist ein eigenes Interface, darüber kann man die Transaction öffnen, und wieder schließen sowie mitteilen ob es im Ablauf der Action ein Problem gab.  Da die Implementierung Datenbankabhängig ist gehe ich hier nicht Groß darauf ein, nur der Hinweis das bei EndTransaction() bei einem Problem die Transaction mit einem Rollback() beendet wird sonst mit einem Commit().

public interface IDatabaseTransaction 
{
    void BeginTransaction();
    void EndTransaction();
    void ExceptionWhileTransaction();
}
In meinen Anwendungen habe ich immer einen Basis-Controller von dem ich alle meine Controller ableite. Ich hoffe Du machst dies auch so! Somit ist es sehr enfach die Erzeugung des IActionInvoker auszutauschen und den eigenen zu verwenden.

 

public abstract class TransactionController : Controller
{
    public IDatabaseTransaction Transaction { get; set; }

    protected override IActionInvoker CreateActionInvoker()
    {
        return new TransactionalActionInvoker(Transaction,base.CreateActionInvoker());
    }

    protected override void OnException(ExceptionContext filterContext)
    {
        base.OnException(filterContext);
        Transaction.ExceptionWhileTransaction();
    }
}

Nicht viel besonderes, es wird eine Instanz vom TransactionActionInvoker erzeugt und ihr die IDatabaseTransaction sowie der ursprüngliche IActionInvoker übergeben.

Wichtig ist es OnException() zu überschreiben um der IDatabaseTransaction mitzuteilen das eine Exception innerhalb der Action aufgetreten ist.

Die IDatabaseTransaction muss natürlich auch irgendwie in den Controller kommen, dies wird in diesem Fall vom IoC-Container gemacht und zwar per Property-Injection. Ich habe hier der Property-Injection gegenüber der Konstruktor Injection den Vorzug gegeben damit ich die die Abhängigkeit nicht bei jedem zu implementierenden Controller “manuell” bedienen muss. Dies kann man jedoch machen wie man möchte, ein Lookup über den Container oder IServiceLocator wäre auch möglich.

Den Lebenszyklus von IDatabaseTransaction habe ich über den IoC-Container auf pro HttpRequest festgelegt. Dies ist erforderlich, auch ist es erforderlich dass die eigenen Datenbank Session/Connection auf pro HttpRequest festgelegt ist. Es muss sichergestellt werden dass alle Datenbank Aufrufe innerhalb der Action mit derselben Connection bzw. Session aufgerufen werden.


dieser Eintrag ist mir etwas Wert
 
04 Aug
2010

Warum Management der Abhängigkeiten von Komponenten? NU!

Seit einiger Zeit nervt mich folgendes.

Ich arbeite an verschiedenen Projekten, die meisten nutzen auch Komponenten die nicht von mir stammen. Diese wären z.B. xUnit.net, Rhino.Mocks, Automapper, StructureMap usw. usf.

Des weiteren bin ich ein Freund davon alles was man für das Projekt braucht auch unter der Versionkontrolle zu haben um es nach dem ausschecken

  • in Visual Studio öffnen,
  • es kompilieren,
  • auf dem Build-Server starten,
  • Versionspezifische abhängigkeiten habe,
  • usw

ohne dass es dabei zu Problemen kommt und man sofort damit arbeiten kann. Und man nicht schauen muss wo nun noch welche Assembly in welcher Version referenziert wird. Wenn mehrere an dem Projekt arbeiten potenzieren sich die Probleme weil jeder seine Assemblies woanders liegen hat. Somit, alles was geht mit in die Versionskontrolle. Dies sollte jeder so handhaben.

Wo liegt denn jetzt das Problem?

Ist doch alles schön und funktioniert. Nunja, fast, solange die externen komponenten nicht angefasst werden, nicht aktualisiert werden müssen sowie es nur ein Projekt ist. Nun sind auch noch eigenen Komponenten dabei, die zum Teil noch Rege in der Entwicklung sind und öfters aktualisiert werden.

Die Projekte aktuell zu halten, die Komponenten an den richtigen Platz kopieren ist eine nervige und auch für Fehler anfällige Arbeit.

Es wäre doch schön wenn man dies schnell, einfach und mehr oder minder automatisiert machen könnte.

Wir haben 2010, da muss es doch was geben?

Habe mich somit auf den Weg gemacht was zu suchen, was vielleicht eine Art Standard in der .NET Welt ist, Auch soll bei Open Source Projekten der Entwickler der mal kurz reinschnuppern will nicht in weitere Abhänigkeiten gedrängt werden, oder andere Teammitglieder müssen es nicht unbedingt verwenden um das Projekt zu bauen oder daran zu entwickeln.

Irgendwie nichts gefunden was meine Erwartungen und Bedürfnisse erfüllte. Als Software-Entwickler habe ich dies auf die lange MMMM-Liste gestellte (müsste man mal machen).

Ruby hat das Problem schon gelöst

Schaut man in die Ruby-Welt so gibt es da schon gar ewig RubyGems. Kleine Komponenten die man sich sehr einfach lokal auf den Rechner kopieren kann und immer aktuell halten kann.

Dies haben sich Dru Seller, Chris Patterson und ein paar andere auch gedacht und entwickelten NU. Ein kleines Tools welches auf RubyGems aufsetzt und somit auf bewährten. Dies um ein paar Features ergänzt die für “uns” wohl interssant sind.

NU betritt die Bühne

NU existierst nun schon eine ganze Weile aber seit 2-3 Wochen beginnt das ganze an Fahrt aufzunehmen, Nach der Installation von Ruby, Gems und Nu (ist total einfach) kann man schon loslegen.

nu install nhibernate

 

Und kurze später hat man in dem aktuellen Ordner einen LIB Ordner (einstellbar). Indem sich folgendes befindet.

  • castle.core
  • castle.dynamicproxy2
  • log4net
  • nhibernate
  • nlog

Es wurde NHibernate und dessen Abhängigkeiten installiert. Zuerst in das lokale Gem-Repository und dann in das Projekt. Und von da aus natürlich in die Versionverwaltung.

Auf Tekpub befindet sich ein kostenloses Video dazu, dies zeigt in knapp 3 Minuten was NU ist und kann.

http://tekpub.com/view/dotnet-oss/nu

Eigene Gems zu erstellen ist auch sehr einfach

Dazu einfach ein gemspec erstellen und über gem bauen

 

version = File.read(File.expand_path("../VERSION",__FILE__)).strip  

Gem::Specification.new do |spec|
  spec.name        = 'fluentmetadata'
  spec.version     = version
  
  spec.has_rdoc = false
  spec.files = Dir["lib/FluentMetadata.*.dll", "lib/Readme.txt"]
  spec.files.reject! { |fn| fn.include? "Specs.dll"  }
  spec.description = 'FluentMetadata is describing Object-Metadata on one place, and using it from ASP.NET MVC 2 & 3, FluentNHibernate and EntityFramework 4 CodeFirst with EF Feature CTP 4'
  spec.summary     = 'FluentMetadata - Metadata on one place for .NET'
  
  spec.author			 = 'Albert Weinert'
  spec.email             = 'info@der-albert.com'
  spec.homepage          = 'http://wiki.github.com/DerAlbertCom/FluentMetadata/'
end

 

Das bauen eines Gems ist sehr einfach

gem build fluentmetada
gem install fluentmetada

 

Dies natürlich am besten direkt im Build-Skript machen und man braucht sich nicht mehr zu kümmern.

Und schon hat man das Gem im lokalen Repository und fertig. Mit “nu install” kann man dies nun in andere Projekte übernehmen und aktualisieren (am besten wieder über ein Skript oder Batch). Und braucht sich nicht mehr darum zu kümmen wo der kram nun herkommt.

Aktuell kann man die dann noch per “gem push” auf Rubygems.org pushen und dort sieht es dann so aus.

http://rubygems.org/gems/fluentmetadata

Ein Buildscript (mit psake) welches das Gem immer wieder erzeugt kann so aussehen

http://github.com/DerAlbertCom/FluentMetadata/blob/master/default.ps1

Zukunft

Natürlich bringt so ein System nur was wenn es viele, wenn nicht gar alle verwenden. Dann hat man ein schönes Eco-System und viel weniger Probleme und arbeit. Also nutzt es.

Natürlich ist Rubygems.org auf Dauer keine Lösung für uns, und ein eigener Platz für .net gems wäre fein, da wird schon dran gearbeitet und wird nicht mehr so lange auf sich warten lassen.

Aktuell findet man unter http://nu.wikispot.org/ alle wichtigen Informationen und Links.

NU selbst ist weiterhin in Entwicklung in der Mailingliste diskutiert man gerade um es um weitere .net Specifika zu erweitern, mir reicht erstmal die jetzige Funktionalität es fehlen nur weitere Gems für .NET. Also macht mit.

Technorati Tags: ,,,

dieser Eintrag ist mir etwas Wert
 
02 Aug
2010

Ein SubText Blog mit dotnet-kicks.de Button

dotnet-kicks.de erfreut sich in deutschen .NET Welt ja doch einiger Beliebtheit, also bietet es sich an dies auch im eigenen Blog zu unterstützen. Ich habe nun ein Control gebaut mit dem es ganz einfach geht.

Als erstes erstellt man in dem Controls-Ordner seines Skins die Datei KickIt.ascx, und füllt diese mit folgendem Inhalt.

<%@ Control Language="C#" ClassName="KickItDeControl"  
    Inherits="Subtext.Web.UI.Controls.CurrentEntryControl"%>
<% 
	string urlUrl = UrlEncode(Entry.FullyQualifiedUrl );
	string urlTitle = UrlEncode(HttpUtility.HtmlDecode(Entry.Title));
%>
<a href="http://dotnet-kicks.de/kick/?url=<%=urlUrl%>&amp;title=<%=urlTitle%>">
<img src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=<%=urlUrl%>" 
     border="0" alt="kick it on dotnet-kicks.de" /></a>

Dies ist ein einfaches Control welches den dotnet-kicks.de-Code erzeugt. Nun muss man das Control noch dort eintragen wo man es Anzeigen lassen (üblicherweise Day.ascx undViewPost.ascx). Zuerst muss das UserControll wie in ASP.NET WebForms üblich registriert werden, dann kann es verwendet werden.
<%@ Register TagPrefix="awn" TagName="KickItDe" Src="KickItDe.ascx" %>

<!-- und nun an die Stelle wo es angezeigt werden soll -->

<awn:KickItDe runat="server"/>

Von nun wird auf jeder geänderten Seite der dotnet-Kicks.de Button angezeigt.

Technorati Tags: ,

dieser Eintrag ist mir etwas Wert
 
02 Aug
2010

Ein SubText Blog mit Flattr-Button

Nutzt man SubText für das eigenen Blog und möchte man Flattr damit verwenden, so kann man dies auf verschiedenen Weise machen. Hier nun wie ich es gemacht habe.

Als erstes erstellt man in dem Controls-Ordner seines Skins die Datei Flattr.ascx, und füllt diese mit folgendem Inhalt

<%@ Control Language="C#" ClassName="FlattrControl" 
    Inherits="Subtext.Web.UI.Controls.CurrentEntryControl"%>
<script runat="server">
	public string FlattrId {get;set;}	
</script>
<%
	string htmlTitle = HttpUtility.HtmlDecode(Entry.Title).Replace("'","\"");
%>
<script type="text/javascript">
var flattr_btn = 'compact';
var flattr_uid = '<%=FlattrId%>';
var flattr_tle = '<%=htmlTitle%>';
var flattr_dsc = '<%=htmlTitle%>';
var flattr_cat = 'text';
var flattr_lng = 'de_DE';
var flattr_url = '<%=Entry.FullyQualifiedUrl%>';
</script>
<script src="http://api.flattr.com/button/load.js" type="text/javascript"></script>

Dies ist ein einfaches Control welches den Flattr-Code erzeugt. Nun muss man das Control noch dort eintragen wo man es Anzeigen lassen (üblicherweise Day.ascx und ViewPost.ascx). Zuerst muss das UserControll wie in ASP.NET WebForms üblich registriert werden, dann kann es verwendet werden.

<%@ Register TagPrefix="awn" TagName="Flattr" Src="Flattr.ascx" %>

<!-- und dann dort wie man es anzeigen lassen will, als FlattrID muss man die 
 eigene Nummer eintragen -->

<awn:Flattr FlattrId="YourID" runat="server"/>

Von nun wird auf jeder geänderten Seite ein Flattr-Button erstellt.

Technorati Tags: ,

dieser Eintrag ist mir etwas Wert
 
28 Jul
2010

Globale Namespaces für die Razor-Syntax und den ASP.NET WebPages

Wenn man bei WebForms nicht auf jeder Page oder jedem UserControl die notwendigen Namespace importieren möchte. So hat man diese in der Web.config hinterlegt.

Dies funktioniert wunderbar bei WebForms und der WebForm-ViewEngine unter ASP.NET MVC.

Mit den neuen WebPages (.cshtml) und der Razor-Syntax kann man mit

@using Regularly.Models
@using Regulary.Areas.Administration.Models

auch entsprechende Namespaces der Template bekannt machen, Jedoch funktioniert der Weg über die web.config nicht (ob sich dies ändert steht wohl nicht nicht fest).

Aber man einen anderen Weg gehen, dazu muss man beim Application-Start über die Klasse CodeGeneratorSettings die Namespaces hinzufügen.

CodeGeneratorSettings.AddGlobalImport("Regularly.Models");
CodeGeneratorSettings.AddGlobalImport("Regularly.Extensions");

Diese Klasse befindet sich im Namespace Microsoft.WebPages.Compilation


dieser Eintrag ist mir etwas Wert
 
21 Jul
2010

Neue Informationen hier im Blog

Da ich hier und da Anfragen nach Vorträgen bekomme habe ich hier im Blog nun angefangen die Vorträge die ich halte zu hinterlegen. Diese Liste wird mit der Zeit erweitert.

Firmen und User Groups können bei mir für einen Vortrag vor Ort anfragen.

 

Technorati Tags: ,,,

dieser Eintrag ist mir etwas Wert
 
06 Jul
2010

Eigene Namensregeln in ReSharper für xUnit.NET basierte Tests

Ich habe heute ein PlugIn für ReSharper veröffentlicht, mit dem möglich ist spezielle Naming-Styles in ReSharper für xUnit.NET und xUnitBDDExtensions basierte Unit Test festzulegen.

Im readme.txt ist erklärt wie man es installiert. Hier ein paar Screenshots zur Verwendung im ReSharper.

ReSharper-Options-NamingStyle

Dort nun Advanced Settings anklicken.

ReSharper-Options-Advande-Naming-Settings

Nun eine eigene Naming Rule hinzufügen. z.B. BDD Style und folgendes

auswählen.

ReSharper-Options-NamingStyle-BDD


Das war’s dann schon. Viel Spaß.

Hier geht’s zur Projekt Seite auf GitHub

 


dieser Eintrag ist mir etwas Wert