Jak współdzielić kod między projektami / rozwiązaniami w Visual Studio?


229

Mam dwa rozwiązania, które mają wspólny kod, więc chciałbym go wyodrębnić i udostępnić między nimi. Ponadto chciałbym móc samodzielnie wydać tę bibliotekę, ponieważ może być przydatna dla innych.

  • Jak najlepiej to zrobić w Visual Studio 2008?
  • Czy projekt występuje w więcej niż jednym rozwiązaniu?
  • Czy mam osobne rozwiązanie dla oddzielnego fragmentu kodu?
  • Czy rozwiązanie może zależeć od innego?

15
Jego 2014. Nuget jest odpowiedzią.
Ravi

1
@Ravi Chciałem zmodularyzować aplikację sieci Web Visual Studio opracowaną w moim biurze. Jednak gdy próbuję wymyślić modułowość aplikacji sieci Web Visual Studio na różne aplikacje internetowe, pojawia się zależność cykliczna między komponentami, która jest nieprawidłowa. nie można zmodularyzować projektu POCO dla każdej planowanej aplikacji sieci Web, ponieważ istnieje zbyt duża zależność. Czy mogę skorzystać z Nuget, aby pomóc w modularyzacji?
CS Lewis

Odpowiedzi:


70

Do projektu może odnosić się wiele rozwiązań.

Umieść bibliotekę lub kod podstawowy w jednym projekcie, a następnie odwołaj się do tego projektu w obu rozwiązaniach.


150
Ok, ale jak? Jakieś instrukcje?
cja

2
Ta (stara) odpowiedź sama w sobie jest niekompletna z powodu powstania wielu zestawów: jednak w połączeniu z ILMerge - zwłaszcza z opcją internalizacji - staje się bardzo potężnym rozwiązaniem.
user2246674

2
@ user2246674: dlaczego jest niekompletny z powodu wielu zespołów? OP nie powiedział nic o pojedynczym zgromadzeniu.
John Saunders

1
@Jfly: Zmiana nazwy rzeczy, które nie są publicznie widoczne, nie wpłynie na kod zewnętrzny. Zmiana nazw rzeczy, które publicznie widoczne, powinna odbywać się tylko wtedy, gdy wszystkie projekty korzystające ze wspólnego kodu i samego wspólnego kodu znajdują się w jednym rozwiązaniu. Możesz ręcznie tworzyć „wzorcowe” rozwiązania, które zawierają wszystkie te projekty i które są używane tylko w tym celu.
John Saunders

1
To zależy, co masz na myśli przez inną instancję. Prawdopodobnie dobrze by było zacząć nowe pytanie z kilkoma szczegółami.
ilivewithian

248

Możesz „połączyć” plik kodu między dwoma projektami. Kliknij projekt prawym przyciskiem myszy, wybierz Add-> Existing item, a następnie kliknij strzałkę w dół obok Addprzycisku:

Screengrab

Z mojego doświadczenia wynika, że ​​łączenie jest prostsze niż tworzenie biblioteki. Połączony kod daje pojedynczy plik wykonywalny z jedną wersją.


9
Słodko - to była odpowiedź, której szukałem. Nie chciałem kolekcji bibliotek DLL. na zdrowie
CAD bloke

63
Dlaczego miałbyś to zrobić w ten sposób? Właśnie dlatego mamy biblioteki, enkapsulację. Nie widzę żadnego uzasadnienia biznesowego ani logicznego uzasadnienia, dlaczego miałbyś to zrobić.
Ryan Ternier

16
Ponadto Twoje linki mogą nie być pod tą samą kontrolą źródła. To bardzo niebezpieczna sugestia.
Kugel

11
Są sytuacje, w których to rozwiązanie jest przydatne. Jako przykład rozwijam w programie InfoPath 2007, w którym wdrożenie oddzielnej biblioteki DLL w programie SharePoint nie jest proste. Aby udostępnić wspólną funkcjonalność między formularzami programu InfoPath, bardzo przydatne jest podejście do pliku klasy połączonej. Jest umieszczony jeden poziom powyżej indywidualnych projektów formularzy, a wszystko jest kontrolowane przez źródło na poziomie głównym.
Oliver Gray

6
Jako kolejny przykład przydatności powiedz, że tworzysz dwie aplikacje, które muszą się ze sobą komunikować. Jeden ma 64 bity, a drugi 32, więc niekoniecznie potrzebujesz osobnych bibliotek DLL zbudowanych z tego samego kodu, aby odwoływały się do każdego projektu. W ten sposób możesz naśladować funkcjonalność c korzystania z pliku .h.
user912447,

33

File > Add > Existing Project...pozwoli Ci dodawać projekty do obecnego rozwiązania. Właśnie to dodałem, ponieważ żaden z powyższych postów tego nie wskazuje. Umożliwia to dołączenie tego samego projektu do wielu rozwiązań.


1
To działa; z drugiej strony nie łączy obu projektów w jeden zestaw.
Ian Boyd

24

Państwo może zawierać projekt w więcej niż jedno rozwiązanie. Nie sądzę, że projekt ma pojęcie, którego rozwiązania jest częścią. Inną alternatywą jest jednak zbudowanie pierwszego rozwiązania w znanym miejscu i odniesienie do skompilowanych plików binarnych. Ma to tę wadę, że trzeba będzie trochę popracować, jeśli chcesz odwoływać się do różnych wersji w zależności od tego, czy budujesz konfigurację wydania, czy debugowania.

Nie sądzę, aby można było uzależnić jedno rozwiązanie od drugiego, ale można wykonać automatyczne kompilacje w odpowiedniej kolejności za pomocą niestandardowych skryptów. Zasadniczo traktuj swoją wspólną bibliotekę tak, jakby była inną zależnością strony trzeciej, taką jak NUnit itp.


W projekcie nie ma informacji o tym, gdzie są przechowywane pakiety nugetów, co można zmienić, otwierając rozwiązanie, co może prowadzić do problemów podczas kompilacji, dlatego jest to preferowane rozwiązanie.
Shane Courtrille,

23

Możesz wstawić symbole wieloznaczne za pomocą następującej techniki (w taki sposób zapisywane jest rozwiązanie @ Andomar w .csproj)

<Compile Include="..\MySisterProject\**\*.cs">
  <Link>_Inlined\MySisterProject\%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>

Wtrącić:

    <Visible>false</Visible>

Jeśli chcesz ukryć pliki i / lub uniemożliwić rozwinięcie symbolu wieloznacznego, jeśli dodasz lub usuniesz element z folderu „wirtualnego istniejącego elementu”, jak MySisterProjectwyżej.


Niezłe. To wygląda na miłe, lekkie rozwiązanie, jeśli wybaczysz kalambur.
CAD bloke

@Cad bloke: To na pewno działa dobrze (podobnie jak twoja gra słów :), ale jest wiele do powiedzenia, aby zrobić wszystko, aby uniknąć linków w pierwszej kolejności
Ruben Bartelink

2
@CAD Bloke: Tak, to jest fajne. Dla jasności powiem wprost, na wypadek, gdyby komuś to pomogło ... Możesz rozładować / przeładować projekt, aby pobrać zmiany. (Alt-P, L dwa razy). Problem VS2010 polega na tym, że pliki .targets itp. <ImportEdowane do plików .csproj są buforowane, dopóki nie przeładujesz rozwiązań, tak jak mówisz.
Ruben Bartelink,

3
Oto moja najnowsza wersja motywu wieloznacznego ... <Compile Include = ".._ Src * *. " Exclude = ".._ Src \ Properties \ AssemblyInfo.cs; .._ Src \ bin * * .; .._ Src \ obj * * .; .._ Src ***. Csproj; .._ Src ***. User; .._ Src ***. Vstemplate "> <Link> Src \% (RecursiveDir)% (Nazwa pliku)% (rozszerzenie) < / Link> </Compile>
CAD bloke

1
@ChrisK Oto więcej wyjaśnień na temat moich edycji w pliku csproj ... theswamp.org/index.php?topic=41850.msg472902#msg472902 . Po prostu edytuję go w Notepad ++. Kiedy go zapisuję VS widzi, że się zmieniło i prosi o ponowne załadowanie. W VS istnieją ustawienia kontrolujące to zachowanie.
CAD bloke

18

Po prostu utworzyłbyś oddzielny projekt biblioteki klas, aby zawierał wspólny kod. Nie musi być częścią żadnego rozwiązania, które z niego korzysta. Odwołaj się do biblioteki klas z dowolnego projektu, który jej potrzebuje.

Jedyną sztuczką jest to, że będziesz musiał użyć odwołania do pliku, aby odwołać się do projektu, ponieważ nie będzie to część rozwiązań, które go dotyczą. Oznacza to, że rzeczywisty zestaw wyjściowy będzie musiał zostać umieszczony w miejscu, do którego może uzyskać dostęp każdy, kto buduje projekt, który się do niego odwołuje. Można to zrobić na przykład poprzez umieszczenie zestawu na udziale.


Wydaje mi się, że jeśli utworzę zdarzenie kompilacji i opublikuję bibliotekę DLL w kontrolowanym źródle folderze _lib w projekcie referencyjnym, to sprawdź, czy biblioteka DLL zadziała. Wydaje się, że to hacky tho.
hanzolo,

1
Jeśli chcesz kontrolować źródła w każdej kompilacji, możesz mieć docelowy kompilator, sprawdzając biblioteki DLL, kopiuj z wyników kompilacji do folderów biblioteki, a następnie sprawdzaj w bibliotekach dll.
John Saunders

8

Możesz uwzględnić ten sam projekt w więcej niż jednym rozwiązaniu, ale na pewno napotkasz problemy w przyszłości (ścieżki względne mogą stać się nieprawidłowe, na przykład podczas przenoszenia katalogów)

Po latach zmagania się z tym w końcu wymyśliłem praktyczne rozwiązanie, ale wymaga ono użycia Subversion do kontroli źródła (co nie jest złe)

Na poziomie katalogu swojego rozwiązania dodaj właściwość svn: externals wskazującą projekty, które chcesz uwzględnić w swoim rozwiązaniu. Subversion wyciągnie projekt z repozytorium i zapisze go w podfolderze pliku rozwiązania. Plik rozwiązania może po prostu używać ścieżek względnych do odniesienia do twojego projektu.

Jeśli znajdę trochę więcej czasu, wyjaśnię to szczegółowo.


Definiując swoje projekty, używaj tylko ścieżek względnych ... To powinno, szczególnie w przypadku wielorazowego użytku, rozwiązać więcej niż mały problem.
xtofl

5
Tylko w celach informacyjnych, svn:externalstwarde linki do repozytorium. Po przeniesieniu repozytorium linki zewnętrzne nadal wskazują stare repozytorium.
Andomar

W przypadku git możesz użyć SubTree SVN: odpowiedniki zewnętrzne w GIT?
Michael Freidgeim

8

Wyodrębnij wspólny kod do projektu biblioteki klas i dodaj ten projekt biblioteki klas do swoich rozwiązań. Następnie możesz dodać odwołanie do wspólnego kodu z innych projektów, dodając odwołanie do projektu do tej biblioteki klas. Zaletą posiadania odwołania do projektu w przeciwieństwie do odwołania do pliku binarnego / zestawu jest to, że jeśli zmienisz konfigurację kompilacji na debugowanie, wydanie, niestandardowe itp., Projekt biblioteki klas wspólnych zostanie również zbudowany na podstawie tej konfiguracji.


5

Dobrym pomysłem jest utworzenie biblioteki klas dll, która zawiera wszystkie typowe funkcje. Każde rozwiązanie może odwoływać się do tej biblioteki dll niezależnie, niezależnie od innych rozwiązań.

Rzeczywiście, w ten sposób zorganizowane są nasze źródła w mojej pracy (i wierzę w wiele innych miejsc).

Nawiasem mówiąc, rozwiązanie nie może jawnie zależeć od innego rozwiązania.


1
Uważam, że jest to jeden z największych punktów pytania, którego mnóstwo ludzi nie rozumie.
Del Lee

5

Są to dwa główne etapy

1- Tworzenie biblioteki dll C ++

W studio wizualnym

New->Project->Class Library in c++ template. Name of project here is first_dll in 
visual studio 2010. Now declare your function as public in first_dll.h file and 
write the code in first_dll.cpp file as shown below.

Kod pliku nagłówka

// first_dll.h

using namespace System;

namespace first_dll 
{

public ref class Class1
{
public:
    static double sum(int ,int );
    // TODO: Add your methods for this class here.
};
}

Plik CPP

//first_dll.cpp
#include "stdafx.h"

#include "first_dll.h"

namespace first_dll
{

    double Class1:: sum(int x,int y)
    {
        return x+y;
    }

 }

Sprawdź to

**Project-> Properties -> Configuration/General -> Configuration Type** 

tą opcją powinna być biblioteka dynamiczna (.dll) i teraz buduj rozwiązanie / projekt.

Plik first_dll.dll jest tworzony w folderze debugowania

2- Łączenie go w projekcie C #

Otwórz projekt C #

Rightclick on project name in solution explorer -> Add -> References -> Browse to path 
where first_dll.dll is created and add the file.

Dodaj tę linię u góry w projekcie C #

Using first_dll; 

Teraz do funkcji z biblioteki dll można uzyskać dostęp za pomocą poniższej instrukcji w niektórych funkcjach

double var = Class1.sum(4,5);

Stworzyłem dll w projekcie c ++ w VS2010 i użyłem go w projekcie VS2013 C #. To działa dobrze.



4

Jeśli próbujesz współdzielić kod między dwoma różnymi typami projektów (tj. Projekt na komputery stacjonarne i projekt mobilny), możesz zajrzeć do folderu rozwiązań udostępnionych . Muszę to zrobić dla mojego obecnego projektu, ponieważ zarówno projekty mobilne, jak i stacjonarne wymagają identycznych klas, które znajdują się tylko w 1 pliku. Jeśli pójdziesz tą drogą, każdy projekt, do którego podłączony jest plik, może wprowadzić w nim zmiany, a wszystkie projekty zostaną odbudowane na podstawie tych zmian.


Jak to działa Stevoni? Czy możesz podać więcej informacji?
Steve Dunn,

@ SteveDunn zamieściłem poradnik na moim bardzo rzadko aktualizowanym blogu (głupia szkoła i praca utrudniają zabawę w życiu). Można go znaleźć tutaj
Stevoni,

4

Jest bardzo dobry przypadek użycia „dodawania istniejących łączy plików” podczas ponownego wykorzystywania kodu w projektach, i wtedy trzeba odwoływać się i obsługiwać różne wersje bibliotek zależnych.

Tworzenie wielu zestawów z odniesieniami do różnych zestawów zewnętrznych nie jest łatwe do zrobienia inaczej bez powielania kodu lub stosowania sztuczek z kontrolą kodu źródłowego.

Uważam, że najłatwiej jest utrzymać jeden projekt na potrzeby programowania i testów jednostkowych, a następnie utworzyć projekty „kompilacji” przy użyciu istniejących łączy plików, gdy trzeba utworzyć zestawy, które odwołują się do różnych wersji tych zewnętrznych zestawów.


2

Jednym prostszym sposobem włączenia pliku klasy jednego projektu do innych projektów jest dodanie projektu do istniejącego rozwiązania, a następnie dodanie odwołania DLL nowego projektu do istniejącego projektu. Na koniec możesz użyć metod dodanej klasy, odszyfrowując przy użyciu dyrektywy na górze dowolnej klasy.


2

Począwszy od VisualStudio 2015, jeśli trzymasz cały swój kod w jednym rozwiązaniu, możesz udostępniać kod, dodając współdzielony projekt . Następnie dodaj odniesienie do tego współużytkowanego projektu dla każdego projektu, w którym chcesz użyć kodu, a także odpowiednie dyrektywy przy użyciu.


2

Teraz możesz użyć projektu współdzielonego

Shared Project to świetny sposób na dzielenie wspólnego kodu w wielu aplikacjach. Doświadczyliśmy już typu Shared Project w Visual Studio 2013 w ramach Windows 8.1 Universal App Development, ale w Visual Studio 2015 jest to samodzielny nowy szablon projektu; i możemy go używać z innymi rodzajami aplikacji, takimi jak konsola, komputer stacjonarny, telefon, aplikacja sklepowa itp. Tego typu projekty są niezwykle pomocne, gdy chcemy udostępnić wspólny kod, logikę oraz komponenty dla wielu aplikacji na jednej platformie . Umożliwia to również dostęp do specyficznych dla platformy interfejsów API, zasobów itp.

wprowadź opis zdjęcia tutaj

Aby uzyskać więcej informacji, sprawdź to

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.