+1 for Caliburn.Micro + Autofac. I've used several composite application frameworks and IOC containers over the years, and IMO this is a winning combination: for small apps all the way up to enterprise level.
Caliburn.Micro, given it's small surface area, fills the gaps in all the right areas to just the right degree without being overbearing. Opt-in only as much as you need. Rob's articles also make it relatively easy for new devs to ramp-up. In my experience it has been well received by devs, rather than "oh no, not another framework to learn...". I would say though it's the sort of framework that you may only truly appreciate after you've done a few tours of duty using more mainstream or traditional approaches. Craig. On 29 November 2011 10:51, <[email protected]> wrote: > Send ozwpf mailing list submissions to > [email protected] > > To subscribe or unsubscribe via the World Wide Web, visit > http://prdlxvm0001.codify.net/mailman/listinfo/ozwpf > or, via email, send a message with subject or body 'help' to > [email protected] > > You can reach the person managing the list at > [email protected] > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of ozwpf digest..." > > Today's Topics: > > 1. Re: Getting up to speed in wpf (Scott Barnes) > > > ---------- Forwarded message ---------- > From: Scott Barnes <[email protected]> > To: ozWPF <[email protected]> > Date: Tue, 29 Nov 2011 09:38:36 +1000 > Subject: Re: Getting up to speed in wpf > Dude, just embrace caliburn micro. That goes for all, in the last 5-6 > years both as an MSFT Evangelist, WPF / SL Product Manager and cubicle > co-worker for more teams than I care to count i have seen one consistent > thing over and over ... over complication of the basics. > > I've watched countless teams adopt PRISM only to have it backfire down the > road and its probably with the Patterns & Practices team abandoned that > evil seed and instead doubled down on MEF. Even with MEF you get a lot of > functionality that you don't use, but when you combine Caliburn Micro + > MEF, now we start to see something happen that makes sense. > > Autofac is in there as well, local aussie Nicholas is quite the talented > dev, and Autofac approach to IoC is the cheapest and laziest route to > victory. I kid you not, you will get in and out of your code base fast and > effeciently with Caliburn Micro as it removes a lot of the architectural > overheads but still empowers you should want to deviate from the master > plan.. its kind of a passive impact to your code base and best of all other > devs you need to work with can give you advice as they don't have to > reverse engineer your own concoction that you dreamed up - which is kinda > the same but not? > > I don't personally pick frameworks quickly as I came from a java > background where we built frameworks to actually solve problems that > tooling at times didn't pick up the slack on. In the .NET scene i see > tooling that does what frameworks should do and frameworks doing things > that often don't offer value other than "look i am attempting to make my > own solution that if you type a decimal point it creates an instant > application!!!" > > Rant over ... :)_ > > > --- > Regards, > Scott Barnes > http://www.riagenic.com > > > On Tue, Nov 29, 2011 at 1:36 AM, Martin Crimes < > [email protected]> wrote: > >> There were only 2 of us on the project for the 1st 8 months (and my >> colleague spent a lot of that time on the WCF end of things), so I do >> appreciate how difficult it ends up being. My rule of thumb has always >> been to write what you need when you need it, when you find yourself >> copying it for the 2nd or 3rd time to use elsewhere, it’s time to make >> yourself a baseclass and derive from then on. Trying to second guess when >> it’s really worth writing base classes & what they may need to do in the >> future will drive you insane and lead to endless refactoring unless you’re >> amazingly prescient.**** >> >> ** ** >> >> One thing which we do a little differently than most is to use >> ObjectDataProviders as our data sources rather than binding directly >> through an assigned DataContext (most of the time). What I found was >> confusing early on with complex data sources, was telling from looking at >> the XAML exactly what on earth any control was binding to exactly.**** >> >> ** ** >> >> So when our IOC creates the View and ViewModel classes, it passes the VM >> instance into the View via a method a bit like this :**** >> >> ** ** >> >> /// <summary>**** >> >> /// The view model associated with this view.**** >> >> /// </summary>**** >> >> public AccountWalletVM ViewModel**** >> >> {**** >> >> get**** >> >> { **** >> >> return _viewModel; **** >> >> }**** >> >> set**** >> >> {**** >> >> _viewModel = value;**** >> >> ModelObjectDataProvider modp = >> ((ModelObjectDataProvider)this.FindResource("ViewModel"));**** >> >> modp.ObjectInstance = _viewModel;**** >> >> modp.Refresh();**** >> >> }**** >> >> }**** >> >> private AccountWalletVM _viewModel = null;**** >> >> ** ** >> >> Then in the XAML <UserControl.Resources> section :**** >> >> ** ** >> >> <ss:ModelObjectDataProvider x:Key="ViewModel"**** >> >> d:IsDataSource="True"**** >> >> ObjectType="{x:Type >> ViewModels:AccountWalletVM}" />**** >> >> ** ** >> >> The ModelObjectDataProvider is just a class which derives from the >> standard ObjectDataProvider, but does some deferring of the bindings until >> the data’s actually there. I’ve included the class definition at the >> bottom of the email for reference (it’s rather fat with comments, but >> simple in concept).**** >> >> ** ** >> >> I can’t entirely remember all the discussion and approaches we tried when >> settling on this standard, but now most of our XAML binding looks like this >> below. I remember one of the issues we had early on with Binding was that >> we ended up with grid/itemscollections where we wanted some data from 1 >> data source & then something like the Button Command or choices for a >> ComboBox to come from another object.. Our early VMs got very complex >> because of a belief we could only really bind to one thing. Being explicit >> about the main VM to which the View is bound, allows you to leap out at any >> time to look at something exposed from that VM, regardless of how many >> objects down a collection/hierarchy of properties you are at that time… It >> adds some extra boilerplate which goes into a lot of your bindings (though >> you can cheat and stick the DataContext on a GroupBox to avoid the need to >> add the source for all your child controls then), but saves much complex >> walking of Ancestors to find the data source you want.**** >> >> ** ** >> >> ** ** >> >> <DataGrid x:Name="dgWallets"**** >> >> ItemsSource="{Binding Source={StaticResource >> ViewModel}, Path=Wallets, Mode=OneWay}">**** >> >> <DataGrid.Columns>**** >> >> <DataGridTextColumn Header="{Binding >> Source={StaticResource ViewModel}, Path=Strings.V_ListHeadingWalletName, >> Mode=OneTime}"**** >> >> >> Binding="{Binding Path=Name}" />**** >> >> <DataGridTemplateColumn>**** >> >> <DataGridTemplateColumn.CellTemplate>**** >> >> <DataTemplate>**** >> >> <Button Style="{DynamicResource >> DeleteButtonStyle}"**** >> >> Command="{Binding >> Source={StaticResource ViewModel}, Path=DeleteWalletCommand}"**** >> >> >> CommandParameter="{Binding}" />* >> *** >> >> </DataTemplate>**** >> >> </DataGridTemplateColumn.CellTemplate>**** >> >> </DataGridTemplateColumn>**** >> >> </DataGrid.Columns>**** >> >> </DataGrid>**** >> >> ** ** >> >> No idea if any of this is of interest to anyone, but figured I’d throw it >> out there incase it helps someone get started.**** >> >> ** ** >> >> Martin**** >> >> ** ** >> >> /// <summary>**** >> >> /// A custom ObjectDataProvider which overrides the ObjectType >> property such that it can be**** >> >> /// used at designtime to link an appropriate dummy data object, while >> ignoring that XAML binding**** >> >> /// value at runtime so that ObjectInstance can be used to set the >> data to which the data provider**** >> >> /// refers.**** >> >> /// </summary>**** >> >> /// <remarks>**** >> >> /// This is necessary because the two ways of setting the content of >> an ObjectDataProvider, ObjectType and**** >> >> /// ObjectInstance are mutually exclusive once they've been called. >> The ObjectType property is much more**** >> >> /// convenient for gaining a design-time binding for design purposes, >> but the ObjectInstance is more**** >> >> /// suitable architecturally when the ViewModel is created or >> populated elsewhere (or shared between views)**** >> >> /// </remarks>**** >> >> public class ModelObjectDataProvider : ObjectDataProvider**** >> >> {**** >> >> bool isInDesignMode = >> (bool)DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue; >> **** >> >> ** ** >> >> private IDisposable m_Defer;**** >> >> ** ** >> >> public ModelObjectDataProvider()**** >> >> {**** >> >> // The class is not interested in the XAML >> declaration!<br/> // IsInitialLoadEnabled is setted to true by >> the base (DataSourceProvider) constructor. **** >> >> // if you listen to the PropertyChanged event, you will see, *** >> * >> >> // that IsInitialLoadEnabled is setted to the XAML value after >> BeginQuery has been called **** >> >> IsInitialLoadEnabled = false;**** >> >> }**** >> >> ** ** >> >> protected override void BeginInit()**** >> >> {**** >> >> // increment DataSourceProvider._deferLevel**** >> >> if (!IsInitialLoadEnabled)**** >> >> {**** >> >> m_Defer = this.DeferRefresh();**** >> >> }**** >> >> base.BeginInit();**** >> >> }**** >> >> ** ** >> >> protected override void EndInit()**** >> >> {**** >> >> // decrement DataSourceProvider._deferLevel**** >> >> if (m_Defer != null)**** >> >> {**** >> >> m_Defer.Dispose();**** >> >> m_Defer = null;**** >> >> }**** >> >> else**** >> >> {**** >> >> base.EndInit();**** >> >> }**** >> >> }**** >> >> ** ** >> >> ** ** >> >> ** ** >> >> /// <summary>**** >> >> /// Gets or sets the type of object to create an instance of.**** >> >> /// </summary>**** >> >> /// <value></value>**** >> >> /// <returns>**** >> >> /// This property is null when the <see >> cref="T:System.Windows.Data.ObjectDataProvider"/> is uninitialized or >> explicitly set to null. If <see >> cref="P:System.Windows.Data.ObjectDataProvider.ObjectInstance"/> is >> assigned, <see cref="P:System.Windows.Data.ObjectDataProvider.ObjectType"/> >> returns the type of the object or null if the object is null. The default >> value is null.**** >> >> /// </returns>**** >> >> /// <exception cref="T:System.InvalidOperationException">**** >> >> /// <see cref="T:System.Windows.Data.ObjectDataProvider"/> is >> assigned both an <see >> cref="P:System.Windows.Data.ObjectDataProvider.ObjectType"/> and an <see >> cref="P:System.Windows.Data.ObjectDataProvider.ObjectInstance"/>; only one >> is allowed.**** >> >> /// </exception>**** >> >> public new Type ObjectType**** >> >> {**** >> >> get { return base.ObjectType; }**** >> >> set**** >> >> {**** >> >> if (!isInDesignMode)**** >> >> {**** >> >> value = null;**** >> >> }**** >> >> ** ** >> >> base.ObjectType = value;**** >> >> ** ** >> >> if (isInDesignMode)**** >> >> {**** >> >> this.Refresh();**** >> >> }**** >> >> ** ** >> >> }**** >> >> }**** >> >> ** ** >> >> ** ** >> >> *From:* [email protected] [mailto:[email protected]] >> *On Behalf Of *Greg Keogh >> *Sent:* 25 November 2011 22:26 >> >> *To:* 'ozWPF' >> *Subject:* RE: Getting up to speed in wpf**** >> >> ** ** >> >> Yep, Thanks Martin for your time on that. You have confirmed a lot of my >> experiences, and perhaps that I’m not mad. So far I have written all my WPF >> alone without the help of a team to build comprehensive helper libraries of >> base classes and utilities. I certainly do find myself copying and pasting >> snippets out of other apps a lot. I also try to separate all the styling >> XAML from the controls. I have been very unhappy with MVVM as it seems to >> stretch the capabilities of binding beyond the breaking point as an >> academic exercise and leads to bizarre quirks and workarounds. I have >> settled on a simple View-Controller pattern which keeps the code behind >> quite thin and allows unit testing of the controllers.**** >> >> ** ** >> >> I am back to coding WPF today and I will be editing more XAML by hand.*** >> * >> >> ** ** >> >> Greg**** >> >> Clarity Retail Systems Limited, Paterson House, Hatch Warren Farm, Hatch >> Warren Lane, Hatch Warren, Basingstoke, >> Hants, RG22 4RA, UK - Company Registration No: 02739937 - Registered in >> England >> >> The contents of this email are intended for the named addressee(s) only. >> It contains information which may be confidential and which may also be >> privileged. If you are not the intended recipient(s) please note that any >> form of disclosure, distribution, copying or use of this communication or >> the information in it or in any attachments is strictly prohibited and may >> be unlawful. If you have received it in error please notify the sender >> immediately by return email or by calling +44(0)1256 365150 and ask for >> the sender. Where the content of this email is personal or otherwise >> unconnected with Clarity Retail Systems Limited or our clients' business, >> Clarity Retail Systems Limited accepts no responsibility or liability for >> such content. It is your responsibility to verify that this email and any >> attachments are free of viruses, as we can take no responsibility for any >> computer viruses. >> >> _______________________________________________ >> ozwpf mailing list >> [email protected] >> http://prdlxvm0001.codify.net/mailman/listinfo/ozwpf >> >> > > _______________________________________________ > ozwpf mailing list > [email protected] > http://prdlxvm0001.codify.net/mailman/listinfo/ozwpf > >
_______________________________________________ ozwpf mailing list [email protected] http://prdlxvm0001.codify.net/mailman/listinfo/ozwpf
