First of all, since I saw you talking about the message bus, I think we need to talk about BC integration first.
You do not need a message bus for communication between the BC; here is an explanation of how I integrate various BCs:
I reveal some public interfaces on each BC (like domain commands - requests and events) and has an intermediate level in my infrastructure that transfers this call to another BC.
Here is an example interface for open commands in BC:
public interface IHandleCommands { void DoSomething(Guid SomeId,string SomeName); }
I also have a similar one for open events
public interface IPublishEvents { void SomethingHappened(Guid SomeId,string SomeName); }
Finally, for my open data (i.e. queries in CQ (R) S), I have a different interface, note that this allows you to remove the connection between your domain model and the request code at any time.
public interface IQueryState { IEnumerable<SomeData> ActiveData(DateTime From=DateTime.Minvalue, ... ); }
And my implementation looks like this:
public class SomeAR:IHandleCommands { IPublishEvents Bus; public SomeAr(IPublishEvents Bus) { this.Bus = Bus; } public void DoSomething(Guid x,string y) { Bus.SomethingHappened(SomeId: x,SomeName: y); } }
After all, when you think about it: things like domain events can be done without messaging; just replace the message classes with the interface members and replace the handlers with the implementation of the interface that will be introduced into your BC.
These handlers then invoke commands on other BCs; they look like glue that connect different BCs to each other (I think workflows / saga about standing up, etc.).
This may be an example handler:
public class WorkFlow : IPublishEvents { public void SomethingHappened(Guid SomeId,string SomeName) { AnotherBC.DoSomething(SomeId,SomeName); } }
This is a simple approach that does not require much effort, and I have used it with great success. If you want to switch to full-blown messaging later, this should be easy to do.
To answer your questions about the user interface:
I think you are too hard on this.
As long as my domain (or can be easily) separated from your user interface, you can easily start with a single user interface project and then split it up for a minute when you start to experience pain somewhere. However, if you split the code, you must split it into BC, so the project structure is consistent.
I find creating a user interface in such a way as to be the most efficient way for me ...