Bartek Szafko

all of the bits and pieces

Archive for the ‘Development’ Category

Ewolucyjne podejście do schematu baz danych

with 4 comments

Ten post chciałem napisać od czasu, gdy sprzedałem zawarty w nim pomysł Michałowi na jednym ze spotkań PG.NET w końcu się udało :)

Jeśli myślisz, że raz stworzysz schemat bazy danych dla swojej aplikacji i już nigdy go nie będziesz zmieniać to jesteś w błędzie. W czasie produkcji może się okazać, że coś zostało pominięte, coś można rozwiazać lepiej, jest błąd albo po prostu trzeba dodać nową funkcjonalność wymagającą zmian w schemacie.

Read the rest of this entry »

Written by Bartłomiej Szafko

Styczeń 9th, 2010 at 5:05 pm

Posted in Development, General

Windows Installer 4.5 i 5.0 – ciekawa funkcjonalność

without comments

W Windows Vista(Installer 4.5) i Windows 7(installer 5.0) jest całkiem ciekawa funkcjonalność – buforowanie instalatorów msi. Rzecz całkiem przydatna, gdy niespecjalnie lubimy komunikaty w stylu “Nie można znaleźć pliku (ulubiony soft).msi”.

Read the rest of this entry »

Written by Bartłomiej Szafko

Listopad 19th, 2009 at 7:59 pm

Posted in Development, WiX

Tagged with , , , ,

Aktualizacje od strony użytkownika

without comments

Aktualizowanie aplikacji to moim zdaniem ważne zagadnienie. Bardzo często aplikacja podlega ciągłym zmianom, dodawane są nowe funkcjonalności, naprawiane błędy(oczywiście:) ). Istotne jest to, w  jaki sposób taką aktualizację widzi użytkownik.

Read the rest of this entry »

Written by Bartłomiej Szafko

Październik 30th, 2009 at 8:16 pm

Posted in Development, General

Tagged with , , ,

Mono i CAB

with 2 comments

image

Mono to otwarta implementacja środowiska .NET tworzona przez Novella – działa na linuxach i mac os.

Z ostatnich wiadomości: Microsoft obiecał, że nigdy nie będzie ścigał projektu mono o licencję, można przeczytać o tym na blogu Miguela, to może umocnić pozycję tego projektu, do tej pory niespecjalnie było wiadomo czy MSFT pozwie  novella i zmusi do zamknięcia, więc raczej nie podchodziłem do projektu na 100% poważnie.

W Mono niestety nie uświadczysz WPF czy WCF, ale jest za to asp .net MVC. Jest też prawie 100% zgodność z Winsforms. Język C# jest w wersji 3.0 i obsługuje LINQ.

Dla Mono jest coś co się nazywa Mono Migration Analyzer (MoMA) – pozwala na sprawdzenie w jakim stopniu aplikacja będzie się uruchamiać na mono.

Wszystko fajnie, ale postanowiłem spróbować jak to wygląda w rzeczywistości na bardziej zaawansowanych aplikacjach.  Wziąłem Smart Client Software Factory w wersji z kwietnia 2008, a konkretnie Quickstarts.BankTeller i przepuściłem przez MoMA, oto  co dostałem:

image

Czyli w sumie nie jest źle! Dokładniejszy raport wygląda tak:

image

Pierwsza z uwag jest spowodowana tym, że w aplikacji jest wywoływana przeglądarka internerowa, której brakuje w Mono – co w sumie jest OK. Drugi brak już jest poważniejszy, ale z tego co kojarze jest w kolejce do zrobienia.

Czyli w sumie powinno się udać uruchomić aplikację w SCSF na linuxie – hmm to otwiera całkiem ciekawe możliwości. Teraz tylko muszę wybrać jakąś dystrybucję ( czy Polish Linux Distribution jeszcze żyje?) zainstalować na wirtualce i sprawdzić jak to działa w praktyce.

PS: Ostatnio pojawił się także ciekawy podcast Scotta Hanselmanna w tym temacie – do posłuchania tutaj.

Written by Bartłomiej Szafko

Lipiec 8th, 2009 at 7:11 pm

Posted in .NET, Development

Iron Python

with 2 comments

O Iron pythonie czytałem już trochę wcześniej, jednak nie miałem okazji go faktycznie spróbować. Okazja na użycie pojawiała się jakiś czas temu – szukałem rozwiązania pozwalającego użytkowniokowi aplikacji mieć wpływ na pewne części aplikacji bez konieczności programowania, ani posiadania środowiska programistycznego. Iron Python nadał się do tego idealnie.

Leon Bambrick ma na swoim blogu świetny przykład:

image

W pierwszym polu tekstowym wpisujemy skrypt, który ma się wykonać po naciśnięciu GO. W skrypcie mamy dostęp do całego obiektu txt, który jest drugim polem edit – tutaj jest przykład pozwalący na zrobienie UpperCase z zaznaczonego tekstu. Całość można wywołać za pomocą prostych komend:

ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = null;
scope = engine.CreateScope();
scope.SetVariable("txt", TargetTextBox);
string code = CommandTextBox.Text.Trim();
ScriptSource source = engine.CreateScriptSourceFromString(code, SourceCodeKind.Statements);
source.Execute(scope); 

Jedyną wadą jest zauważalnie dłuższy czas pierwszego uruchomienia w stosunku do pozostałych. Trzeba pewnie będzie zrobić warmup podczas startu aplikacji.

IronPythona można pobrać z codeplex.

No i ciekawostka – instalator pythona jest napisany przy pomocy Windows Installer Xml.

Written by Bartłomiej Szafko

Maj 24th, 2009 at 9:02 pm

Posted in Development

Tagged with ,

Lokalizacja gotowej aplikacji ASP .NET MVC

with 3 comments

image

No dobra, po godzinach też programuje, ale już dla przyjemności ;) dlatego nikt mi za to nie płaci :D

Sytuacja: gotowa aplikacja w ASP .NET MVC – język wszystkich komunikatów to angielski. Dodatkowo aplikacja nie była przystosowana w żaden sposób do lokalizacji. Można powiedzieć, że jest to typowa brownfield application.

Zadanie: spolszczyć całość aplikacji – zachowując przy tym możliwość pokazania interfejsu użytkownika w pierwotnej wersji językowej.

Pierwsze koty za płoty – rozwiązanie gorsze

Pierwsze rozwiązanie jakie przychodzi na myśl to – tłumaczenie wszystkich tekstów z kontrolerów i modyfikacja widoków. Sposób słaby i nie pozwoli na pokazanie interfejsu w oryginalnym języku.

Drugie rozwiązanie – lepsze

Kontrolery

Przeniesienie wszystkich stringów, które podlegają lokalizacji, z Controllerów do resourców w folderze App_LocalResources. Następnie trzeba stworzyć wersje resourców dla każdego języka.

Trzeba jeszcze wziąć pod uwagę, czy komunikaty są budowane za pomocą String.Format – w moim wypadku tak na szczęście było.

Wyciąganie stringów do resourców – to jest naprawdę mordercze zajęcie – na szczęście po małym wyszukiwaniu znalazłem super wtyczkę do Resharpera – RGreatEx. Wtyczka potrafi wyciągnąć stringi do resourców i w ich miejsce wstawić odpowiednie odwołania. Podobno potrafi także tłumaczyć za pomocą google translate, ale do automatycznego tłumaczenia jestem nastawiony sceptycznie.

Widoki

Zdublowanie plików widoków np About.aspx w wersji angielskiej –> About.pl.aspx w wersji polskiej. Wiem, teoretycznie powinienem też wyciągnąć wszystkie stringi do lokalizacji, jednak(odstawiając na bok różne dogmaty) takie rozwiązanie wydało mi się bardzie sensowne. No dobra, teraz tylko sposób żeby ViewEngine w pierwszej kolejności wyszukał stronę About.pl.aspx, a dopiero w drugiej About.aspx. Okazuje się, że najlepiej w tym celu zrobić własny ViewEngine:

public class LocalizationViewEngine : WebFormViewEngine
    {
        public LocalizationViewEngine() : base()
        {
            ViewLocationFormats = AppendCulture(ViewLocationFormats);
            PartialViewLocationFormats = AppendCulture(PartialViewLocationFormats);
            MasterLocationFormats = AppendCulture(MasterLocationFormats);
        }

        private string [] AppendCulture(string[] arr)
        {
            List<string> ret = new List<string>();
            for (int i = 0; i < arr.Length; i++)
            {
                string s = arr[i];
                s = s.Replace(".aspx",
                              "." + Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName + ".aspx");
                s = s.Replace(".ascx",
                              "." + Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName + ".ascx");
                s = s.Replace(".master",
                              "." + Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName + ".master");
                ret.Insert(0, s);
            }
            ret.AddRange(arr);
            return ret.ToArray();
        }

Trzeba tylko jeszcze powiedzieć MVC, że używamy własnego silnika widoków w global.asax.cs:

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new LocalizationViewEngine());

A w web.config zmienić ustawienia globalization:

<globalization
requestEncoding="utf-8"
responseEncoding="utf-8"
culture="en-US"
uiCulture="pl-PL"
/>

Teraz zostaje tylko nudna część tzn.: wygibasy lingwistyczne i tłumaczenie resource oraz widoków. Jak już jest wszystko wymyślone to średnio chce mi się odwalać czarną robotę ;P

Written by Bartłomiej Szafko

Luty 23rd, 2009 at 11:49 pm

Posted in ASP .NET MVC, Development

15. spotkanie PG.NET

without comments

Najbliższe spotkanie poznańskiej grupy .NET już w czwartek, 29 stycznia od godziny 18:00. Strona i rejestracja na spotkanie jest tutaj.

Modelowanie rzeczywistości w OSLO

Będziemy gościć Marcina Kruszyńskiego, który wystąpi z prelekcją pt "Modelowanie rzeczywistości w OSLO". Temat bardzo ciekawy i szczerze mówiąc wogóle mi nieznany. Wystąpienie Marcina będzie okazją do zapoznania się z tematem. Pozowoliłem sobie poszukać trochę materiałów na ten temat:

eXpress Persistent Objects na tle  innych narzędzi ORM

Michał Korsak opowie o tym jak wygląda ORM ze stajni DevExpress na tle innych narzędzi ORM. To z kolei będzie okazja żeby podyskutować o ORM jak takich, także w świetle mojego poprzedniego posta dotyczącego entity framework.

Written by Bartłomiej Szafko

Styczeń 25th, 2009 at 6:33 pm

Posted in Development, Społeczności

Dlaczego Entity Framework będzie rządzić światem

with 7 comments

Nadrabiając ostatnio zaległości w słuchaniu DotNetRocks w odcinku #411 o ORM-ach Ward Bell podniósł ciekawą kwestię, a mianowicie, że Entity Framework będzie dominującym mapperem obiektowo relacyjnym na rynku. Myśl całkiem przewrotna, szczególnie biorąc pod uwagę “Vote of No Confidence”(Alt.NET podcast – hej tutaj też Ward Bell) ze strony społeczności. Jednak warto odsunąć flamewar i love to hate relationship do MS na bok i spojrzeć na fakty.

Po pierwsze zasoby

Microsoft inwestuje w EF nieprawdopodobne zasoby, takie o których np.: NHibernate może tylko pomażyć. Oczywiście jak zwykle V1 pozostawia trochę do życzenia, ale MS już wielokrotnie dowiódł(patrz Vista –> Windows 7), że jednak potrafi się uczyć na błędach i słuchać klientów, więc następne wersje zapewne będą już o wiele lepsze.

Po drugie literatura

Ward podniósł też ciekawy argument – ile jest opublikowanych książek dotyczących NHibernate – okazuje się, że nie ma :( natomiast już w tej chwili są dostępne conajmniej 3 książki na ten temat.Tutaj ciekawostka – link do bloga Julie Lerman, która sama jest autorką spoooorej książki o Entity Framework.

O EF na C2C

c2c logo male

Julie Lerman będzie prelegentem na konferencji Communities2Communities więc będzie okazja, aby posłuchać o EF prosto z ust ekspertki. Na zeszłorocznej edycji C2C temat EF również był obecny pod postacią prelekcji Jarka Kowalskiego.

Written by Bartłomiej Szafko

Styczeń 24th, 2009 at 11:09 am

Posted in .NET, Development

Wizardy w AERO

with one comment

W viście są dosyć fajnie dopracowane kontrolki – to już wiecie. Moją szczególną uwagę zwróciły wizardy w aero, taki jak na przykład przy dodawaniu nowej drukarki:

image image

To co głównie wyróżnia tego wizarda to przycisk wstecz w lewym górnym rogu i olbrzymi pasek tytułowy ( jak na mój gust nawet za duży).

Szukałem sposobu w jaki by można zrobić takiego wizarda we własnej aplikacji, który byłby zgodny z systemowym. Okazuje się, że istnieje nawet przykład, który pokazuje jak to zrobić w .NET, oczywiście jak zwykle w msdnie sprawa nie jest banalna i wpierw należy pobrać Vista Bridge Controls. Po skompilowaniu wszystkiego możemy zacząć używać fajnych aero wizardów w WPF:

image

image

Zrobienie czegoś takiego wymaga dosyć prostego xamla:

<v:AeroWizard x:Class="Wizard.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:v="clr-namespace:Microsoft.SDK.Samples.VistaBridge.Controls;assembly=VistaBridgeControls"
    xmlns:l="clr-namespace:Wizard"
    MainInstruction="AERO Wizard Test"
    Title="Connect to a workplace"
    >
  <v:AeroWizard.Pages>
    <Page>
      <StackPanel>
        <v:CommandLinkWPF Link="Choice One"  Note="(Recommended)"  Click="OnClick" />
        <v:CommandLinkWPF Link="Choice Two"  Note="(Not Recommended)" Click="OnClick" />
        <v:CommandLinkWPF Link="Choice Three"  Note="(Never Use)" />
      </StackPanel>
    </Page>
    <Page>
      <StackPanel>
        <v:CommandLinkWPF Link="Some Other Link text"  Note="This is a lot of descriptive text, which will enable the user to make a better choice."  Click="OnClick" />
      </StackPanel>
    </Page>
  </v:AeroWizard.Pages>
</v:AeroWizard>

Bardzo poważna wadą takiego rozwiązania to że będzie działać jedynie na Viście, na xp pojawi się komunikat o braku biblioteki dwmapi.dll. Żeby rozwiązać problem trzeba by napisać własną abstrakcję wizarda, która na viscie używałaby aero a na xp jakiegoś domyślnego wyglądu.

Written by Bartłomiej Szafko

Styczeń 4th, 2009 at 7:05 pm

Posted in Development

[EN] WPF: Ribbon in Prism Applications

with 8 comments

Microsoft some time ago published its Ribbon(known from Office 2007) control library for Windows Presentation Foundation. However it turns out that obtaining this library is quite burdensome:

  1. You have to go to a “Office UI Licensing” site and use “License the Office UI”, next you have to login with your Live Id and accept license agreement. Frankly I have no idea what have I agreed to :P at the end you will be able to download WPFRibbonCTP, which contains ribbon control.
  2. I also strongly suggest to download Hands-On-Lab: What’s Coming in WPF:Datagrid, Ribbon and VSM which contains a great tutorial on how to use ribbon in your application. In exercise 2 there is a great app with ribbon which looks like this:

image1[1]

Using Ribbon in Prism

We had a talk on Prism on 12. Poznan .NET User Group Meeting. Szymon Kobalczyk gave a great talk on using Composite Application Library ( aka Prism ) to build great WPF applications. His presentation was very inspiring and gave me a kick-start into Prism. I decided to go on and use ribbon in prism. After some code reading it turned out that I just needed a custom RegionAdapter:

    public class RibbonControlRegionAdapter : RegionAdapterBase<Ribbon>
    {
        private Ribbon m_regionTarget;

        protected override void Adapt(IRegion region, Ribbon regionTarget)
        {
            m_regionTarget = regionTarget;
            regionTarget.Tabs.Clear();
            region.ActiveViews.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(OnActiveViewsChanged);
            foreach ( RibbonTab v in region.ActiveViews)
                regionTarget.Tabs.Add(v);
        }

        private void OnActiveViewsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    foreach (RibbonTab v in e.NewItems)
                        m_regionTarget.Tabs.Add(v);
                    break;

                case NotifyCollectionChangedAction.Remove:
                    foreach (RibbonTab v in e.NewItems)
                        m_regionTarget.Tabs.Remove(v);
                    break;

            }
        }

        protected override IRegion CreateRegion()
        {
            return new AllActiveRegion();
        }
    }

Here is what shell aplication looks like before enabling a  test module ( I know ugly, but it’s not the point:P ):

image6

This is how shell application looks like after enabling module1:

image12

Further development

In this example custom region adapter is built in such way that it only allows you to add whole new tabs to ribbon. You can image an adapter that does reparenting and allows you to add regions even in tabs itself or items to main menu.

Written by Bartłomiej Szafko

Listopad 29th, 2008 at 10:37 pm

Posted in Development